feat: implement DeesTable component with schema-first columns API, data actions, and customizable styles
- Added DeesTable class extending DeesElement - Introduced properties for headings, data, actions, and columns - Implemented rendering logic for table headers, rows, and cells - Added support for sorting, searching, and context menus - Included customizable styles for table layout and appearance - Integrated editable fields and drag-and-drop file handling - Enhanced accessibility with ARIA attributes for sorting
This commit is contained in:
		
							
								
								
									
										472
									
								
								ts_web/elements/dees-table/dees-table.demo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										472
									
								
								ts_web/elements/dees-table/dees-table.demo.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,472 @@ | ||||
| import { type ITableAction } from './dees-table.js'; | ||||
| import * as plugins from '../00plugins.js'; | ||||
| import { html, css, cssManager } from '@design.estate/dees-element'; | ||||
|  | ||||
| interface ITableDemoData { | ||||
|   date: string; | ||||
|   amount: string; | ||||
|   description: string; | ||||
| } | ||||
|  | ||||
| export const demoFunc = () => html` | ||||
|   <style> | ||||
|     ${css` | ||||
|       .demoWrapper { | ||||
|         box-sizing: border-box; | ||||
|         position: absolute; | ||||
|         width: 100%; | ||||
|         height: 100%; | ||||
|         padding: 32px; | ||||
|         background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(0 0% 5%)')}; | ||||
|         overflow-y: auto; | ||||
|       } | ||||
|       .demo-container { | ||||
|         max-width: 1200px; | ||||
|         margin: 0 auto; | ||||
|       } | ||||
|       .demo-section { | ||||
|         margin-bottom: 48px; | ||||
|       } | ||||
|       .demo-title { | ||||
|         font-size: 24px; | ||||
|         font-weight: 600; | ||||
|         margin-bottom: 8px; | ||||
|         color: ${cssManager.bdTheme('hsl(0 0% 9%)', 'hsl(0 0% 95%)')}; | ||||
|       } | ||||
|       .demo-description { | ||||
|         font-size: 14px; | ||||
|         color: ${cssManager.bdTheme('hsl(215.4 16.3% 46.9%)', 'hsl(215 20.2% 65.1%)')}; | ||||
|         margin-bottom: 24px; | ||||
|       } | ||||
|       .theme-toggle { | ||||
|         position: fixed; | ||||
|         top: 16px; | ||||
|         right: 16px; | ||||
|         z-index: 1000; | ||||
|       } | ||||
|     `} | ||||
|   </style> | ||||
|   <div class="demoWrapper"> | ||||
|     <dees-button class="theme-toggle" @click=${() => { | ||||
|       document.body.classList.toggle('bright'); | ||||
|       document.body.classList.toggle('dark'); | ||||
|     }}>Toggle Theme</dees-button> | ||||
|      | ||||
|     <div class="demo-container"> | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Basic Table with Actions</h2> | ||||
|         <p class="demo-description">A standard table with row actions, editable fields, and context menu support. Double-click on descriptions to edit. Grid lines are enabled by default.</p> | ||||
|         <dees-table | ||||
|           heading1="Current Account Statement" | ||||
|           heading2="Bunq - Payment Account 2 - April 2021" | ||||
|           .editableFields="${['description']}" | ||||
|           .data=${[ | ||||
|             { | ||||
|               date: '2021-04-01', | ||||
|               amount: '2464.65 €', | ||||
|               description: 'Printing Paper (Office Supplies) - STAPLES BREMEN', | ||||
|             }, | ||||
|             { | ||||
|               date: '2021-04-02', | ||||
|               amount: '165.65 €', | ||||
|               description: 'Logitech Mouse (Hardware) - logi.com OnlineShop', | ||||
|             }, | ||||
|             { | ||||
|               date: '2021-04-03', | ||||
|               amount: '2999,00 €', | ||||
|               description: 'Macbook Pro 16inch (Hardware) - Apple.de OnlineShop', | ||||
|             }, | ||||
|             { | ||||
|               date: '2021-04-01', | ||||
|               amount: '2464.65 €', | ||||
|               description: 'Office-Supplies - STAPLES BREMEN', | ||||
|             }, | ||||
|             { | ||||
|               date: '2021-04-01', | ||||
|               amount: '2464.65 €', | ||||
|               description: 'Office-Supplies - STAPLES BREMEN', | ||||
|             }, | ||||
|           ]} | ||||
|           dataName="transactions" | ||||
|           .dataActions="${[ | ||||
|             { | ||||
|               name: 'upload', | ||||
|               iconName: 'bell', | ||||
|               useTableBehaviour: 'upload', | ||||
|               type: ['inRow'], | ||||
|               actionFunc: async (optionsArg) => { | ||||
|                 alert(optionsArg.item.amount); | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               name: 'visibility', | ||||
|               iconName: 'copy', | ||||
|               type: ['inRow'], | ||||
|               useTableBehaviour: 'preview', | ||||
|               actionFunc: async (itemArg: any) => {}, | ||||
|             }, | ||||
|             { | ||||
|               name: 'create new', | ||||
|               iconName: 'instagram', | ||||
|               type: ['header'], | ||||
|               useTableBehaviour: 'preview', | ||||
|               actionFunc: async (itemArg: any) => {}, | ||||
|             }, | ||||
|             { | ||||
|               name: 'to gallery', | ||||
|               iconName: 'message', | ||||
|               type: ['footer'], | ||||
|               useTableBehaviour: 'preview', | ||||
|               actionFunc: async (itemArg: any) => {}, | ||||
|             }, | ||||
|             { | ||||
|               name: 'copy', | ||||
|               iconName: 'copySolid', | ||||
|               type: ['contextmenu', 'inRow'], | ||||
|               action: async () => { | ||||
|                 return null; | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               name: 'edit (from demo)', | ||||
|               iconName: 'penToSquare', | ||||
|               type: ['contextmenu'], | ||||
|               action: async () => { | ||||
|                 return null; | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               name: 'paste', | ||||
|               iconName: 'pasteSolid', | ||||
|               type: ['contextmenu'], | ||||
|               action: async () => { | ||||
|                 return null; | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               name: 'preview', | ||||
|               type: ['doubleClick', 'contextmenu'], | ||||
|               iconName: 'eye', | ||||
|               actionFunc: async (itemArg) => { | ||||
|                 alert(itemArg.item.amount); | ||||
|                 return null; | ||||
|               }, | ||||
|             } | ||||
|           ] as ITableAction[]}" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|        | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Table with Vertical Lines</h2> | ||||
|         <p class="demo-description">Enhanced column separation for better data tracking.</p> | ||||
|         <dees-table | ||||
|           heading1="Product Inventory" | ||||
|           heading2="Current stock levels across warehouses" | ||||
|           .showVerticalLines=${true} | ||||
|           .data=${[ | ||||
|             { | ||||
|               product: 'MacBook Pro 16"', | ||||
|               warehouse_a: '45', | ||||
|               warehouse_b: '32', | ||||
|               warehouse_c: '28', | ||||
|               total: '105', | ||||
|               status: '✓ In Stock' | ||||
|             }, | ||||
|             { | ||||
|               product: 'iPhone 15 Pro', | ||||
|               warehouse_a: '120', | ||||
|               warehouse_b: '89', | ||||
|               warehouse_c: '156', | ||||
|               total: '365', | ||||
|               status: '✓ In Stock' | ||||
|             }, | ||||
|             { | ||||
|               product: 'AirPods Pro', | ||||
|               warehouse_a: '0', | ||||
|               warehouse_b: '12', | ||||
|               warehouse_c: '5', | ||||
|               total: '17', | ||||
|               status: '⚠ Low Stock' | ||||
|             }, | ||||
|             { | ||||
|               product: 'iPad Air', | ||||
|               warehouse_a: '23', | ||||
|               warehouse_b: '45', | ||||
|               warehouse_c: '67', | ||||
|               total: '135', | ||||
|               status: '✓ In Stock' | ||||
|             } | ||||
|           ]} | ||||
|           dataName="products" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|        | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Table with Full Grid</h2> | ||||
|         <p class="demo-description">Complete grid lines for maximum readability and structure.</p> | ||||
|         <dees-table | ||||
|           heading1="Server Monitoring Dashboard" | ||||
|           heading2="Real-time metrics across regions" | ||||
|           .showGrid=${true} | ||||
|           .data=${[ | ||||
|             { | ||||
|               server: 'API-1', | ||||
|               region: 'US-East', | ||||
|               cpu: '45%', | ||||
|               memory: '62%', | ||||
|               disk: '78%', | ||||
|               latency: '12ms', | ||||
|               uptime: '99.9%', | ||||
|               status: '🟢 Healthy' | ||||
|             }, | ||||
|             { | ||||
|               server: 'API-2', | ||||
|               region: 'EU-West', | ||||
|               cpu: '38%', | ||||
|               memory: '55%', | ||||
|               disk: '45%', | ||||
|               latency: '25ms', | ||||
|               uptime: '99.8%', | ||||
|               status: '🟢 Healthy' | ||||
|             }, | ||||
|             { | ||||
|               server: 'DB-Master', | ||||
|               region: 'US-East', | ||||
|               cpu: '72%', | ||||
|               memory: '81%', | ||||
|               disk: '92%', | ||||
|               latency: '8ms', | ||||
|               uptime: '100%', | ||||
|               status: '🟡 Warning' | ||||
|             }, | ||||
|             { | ||||
|               server: 'DB-Replica', | ||||
|               region: 'EU-West', | ||||
|               cpu: '23%', | ||||
|               memory: '34%', | ||||
|               disk: '45%', | ||||
|               latency: '15ms', | ||||
|               uptime: '99.7%', | ||||
|               status: '🟢 Healthy' | ||||
|             }, | ||||
|             { | ||||
|               server: 'Cache-1', | ||||
|               region: 'AP-South', | ||||
|               cpu: '89%', | ||||
|               memory: '92%', | ||||
|               disk: '12%', | ||||
|               latency: '120ms', | ||||
|               uptime: '98.5%', | ||||
|               status: '🔴 Critical' | ||||
|             } | ||||
|           ]} | ||||
|           dataName="servers" | ||||
|           .dataActions="${[ | ||||
|             { | ||||
|               name: 'SSH Connect', | ||||
|               iconName: 'lucide:terminal', | ||||
|               type: ['inRow'], | ||||
|               actionFunc: async (optionsArg) => { | ||||
|                 console.log('Connecting to:', optionsArg.item.server); | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               name: 'View Logs', | ||||
|               iconName: 'lucide:file-text', | ||||
|               type: ['inRow', 'contextmenu'], | ||||
|               actionFunc: async (optionsArg) => { | ||||
|                 console.log('Viewing logs for:', optionsArg.item.server); | ||||
|               }, | ||||
|             }, | ||||
|             { | ||||
|               name: 'Restart Server', | ||||
|               iconName: 'lucide:refresh-cw', | ||||
|               type: ['contextmenu'], | ||||
|               actionFunc: async (optionsArg) => { | ||||
|                 console.log('Restarting:', optionsArg.item.server); | ||||
|               }, | ||||
|             } | ||||
|           ] as ITableAction[]}" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|        | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Table with Horizontal Lines Only</h2> | ||||
|         <p class="demo-description">Emphasis on row separation without column dividers.</p> | ||||
|         <dees-table | ||||
|           heading1="Sales Performance" | ||||
|           heading2="Top performers this quarter" | ||||
|           .showHorizontalLines=${true} | ||||
|           .showVerticalLines=${false} | ||||
|           .data=${[ | ||||
|             { | ||||
|               salesperson: 'Emily Johnson', | ||||
|               region: 'North America', | ||||
|               deals_closed: '42', | ||||
|               revenue: '$1.2M', | ||||
|               quota_achievement: '128%', | ||||
|               rating: '⭐⭐⭐⭐⭐' | ||||
|             }, | ||||
|             { | ||||
|               salesperson: 'Michael Chen', | ||||
|               region: 'Asia Pacific', | ||||
|               deals_closed: '38', | ||||
|               revenue: '$980K', | ||||
|               quota_achievement: '115%', | ||||
|               rating: '⭐⭐⭐⭐⭐' | ||||
|             }, | ||||
|             { | ||||
|               salesperson: 'Sarah Williams', | ||||
|               region: 'Europe', | ||||
|               deals_closed: '35', | ||||
|               revenue: '$875K', | ||||
|               quota_achievement: '108%', | ||||
|               rating: '⭐⭐⭐⭐' | ||||
|             }, | ||||
|             { | ||||
|               salesperson: 'David Garcia', | ||||
|               region: 'Latin America', | ||||
|               deals_closed: '31', | ||||
|               revenue: '$750K', | ||||
|               quota_achievement: '95%', | ||||
|               rating: '⭐⭐⭐⭐' | ||||
|             } | ||||
|           ]} | ||||
|           dataName="sales reps" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|        | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Simple Table (No Grid)</h2> | ||||
|         <p class="demo-description">Clean, minimal design without grid lines. Set showGrid to false to disable the default grid.</p> | ||||
|         <dees-table | ||||
|           heading1="Team Members" | ||||
|           heading2="Engineering Department" | ||||
|           .showGrid=${false} | ||||
|           .data=${[ | ||||
|             { | ||||
|               name: 'Alice Johnson', | ||||
|               role: 'Lead Engineer', | ||||
|               email: 'alice@company.com', | ||||
|               location: 'San Francisco', | ||||
|               joined: '2020-03-15' | ||||
|             }, | ||||
|             { | ||||
|               name: 'Bob Smith', | ||||
|               role: 'Senior Developer', | ||||
|               email: 'bob@company.com', | ||||
|               location: 'New York', | ||||
|               joined: '2019-07-22' | ||||
|             }, | ||||
|             { | ||||
|               name: 'Charlie Davis', | ||||
|               role: 'DevOps Engineer', | ||||
|               email: 'charlie@company.com', | ||||
|               location: 'London', | ||||
|               joined: '2021-01-10' | ||||
|             }, | ||||
|             { | ||||
|               name: 'Diana Martinez', | ||||
|               role: 'Frontend Developer', | ||||
|               email: 'diana@company.com', | ||||
|               location: 'Barcelona', | ||||
|               joined: '2022-05-18' | ||||
|             } | ||||
|           ]} | ||||
|           dataName="team members" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|        | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Table with Custom Display Function</h2> | ||||
|         <p class="demo-description">Transform data for display using custom formatting.</p> | ||||
|         <dees-table | ||||
|           heading1="Sales Report" | ||||
|           heading2="Q4 2023 Performance" | ||||
|           .data=${[ | ||||
|             { | ||||
|               product: 'Enterprise License', | ||||
|               units: 45, | ||||
|               revenue: 225000, | ||||
|               growth: 0.23, | ||||
|               forecast: 280000 | ||||
|             }, | ||||
|             { | ||||
|               product: 'Professional License', | ||||
|               units: 128, | ||||
|               revenue: 128000, | ||||
|               growth: 0.15, | ||||
|               forecast: 147000 | ||||
|             }, | ||||
|             { | ||||
|               product: 'Starter License', | ||||
|               units: 342, | ||||
|               revenue: 68400, | ||||
|               growth: 0.42, | ||||
|               forecast: 97000 | ||||
|             } | ||||
|           ]} | ||||
|           .displayFunction=${(item) => ({ | ||||
|             Product: item.product, | ||||
|             'Units Sold': item.units.toLocaleString(), | ||||
|             Revenue: '$' + item.revenue.toLocaleString(), | ||||
|             Growth: (item.growth * 100).toFixed(1) + '%', | ||||
|             'Q1 2024 Forecast': '$' + item.forecast.toLocaleString() | ||||
|           })} | ||||
|           dataName="products" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|        | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Empty Table State</h2> | ||||
|         <p class="demo-description">How the table looks when no data is available.</p> | ||||
|         <dees-table | ||||
|           heading1="No Data Available" | ||||
|           heading2="This table is currently empty" | ||||
|           .data=${[]} | ||||
|           dataName="items" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|  | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Schema-First Columns (New)</h2> | ||||
|         <p class="demo-description">Defines columns explicitly and renders via schema. No displayFunction needed.</p> | ||||
|         <dees-table | ||||
|           heading1="Users (Schema-First)" | ||||
|           heading2="Columns define rendering and order" | ||||
|           .columns=${[ | ||||
|             { key: 'name', header: 'Name', sortable: true }, | ||||
|             { key: 'email', header: 'Email', renderer: (v: string) => html`<dees-badge>${v}</dees-badge>` }, | ||||
|             { key: 'joinedAt', header: 'Joined', renderer: (v: string) => new Date(v).toLocaleDateString() }, | ||||
|           ]} | ||||
|           .data=${[ | ||||
|             { name: 'Alice', email: 'alice@example.com', joinedAt: '2022-08-01' }, | ||||
|             { name: 'Bob', email: 'bob@example.com', joinedAt: '2021-12-11' }, | ||||
|             { name: 'Carol', email: 'carol@example.com', joinedAt: '2023-03-22' }, | ||||
|           ]} | ||||
|           dataName="users" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|  | ||||
|       <div class="demo-section"> | ||||
|         <h2 class="demo-title">Partial Schema + Augment (New)</h2> | ||||
|         <p class="demo-description">Provides only the important columns; the rest are merged in from displayFunction.</p> | ||||
|         <dees-table | ||||
|           heading1="Users (Partial + Augment)" | ||||
|           heading2="Missing columns are derived" | ||||
|           .columns=${[ | ||||
|             { key: 'name', header: 'Name', sortable: true }, | ||||
|           ]} | ||||
|           .displayFunction=${(u: any) => ({ name: u.name, email: u.email, role: u.role })} | ||||
|           .augmentFromDisplayFunction=${true} | ||||
|           .data=${[ | ||||
|             { name: 'Erin', email: 'erin@example.com', role: 'Admin' }, | ||||
|             { name: 'Finn', email: 'finn@example.com', role: 'User' }, | ||||
|             { name: 'Gina', email: 'gina@example.com', role: 'User' }, | ||||
|           ]} | ||||
|           dataName="users" | ||||
|         ></dees-table> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| `; | ||||
							
								
								
									
										1042
									
								
								ts_web/elements/dees-table/dees-table.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1042
									
								
								ts_web/elements/dees-table/dees-table.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user