2023-09-12 13:42:55 +02:00
import { type ITableAction } from './dees-table.js' ;
2026-01-27 10:57:42 +00:00
import * as plugins from '../../00plugins.js' ;
2025-06-27 17:50:54 +00:00
import { html , css , cssManager } from '@design.estate/dees-element' ;
2026-04-08 14:51:49 +00:00
import '@design.estate/dees-wcctools/demotools' ;
2023-09-12 13:42:55 +02:00
2023-09-13 21:13:47 +02:00
interface ITableDemoData {
date : string ;
amount : string ;
description : string ;
}
2023-09-12 13:42:55 +02:00
export const demoFunc = ( ) = > html `
<style>
2025-06-27 17:50:54 +00:00
${ 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;
}
` }
2023-09-12 13:42:55 +02:00
</style>
<div class="demoWrapper">
2025-06-27 17:50:54 +00:00
<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>
2026-04-07 15:32:10 +00:00
<p class="demo-description">A standard table with row actions, editable cells, and context menu support. Double-click any cell to edit. Tab moves to the next editable cell, Enter to the row below, Esc cancels.</p>
2025-06-27 17:50:54 +00:00
<dees-table
heading1="Current Account Statement"
heading2="Bunq - Payment Account 2 - April 2021"
2026-04-07 15:32:10 +00:00
.columns= ${ [
{ key : 'date' , header : 'Date' , sortable : true , editable : true , editor : 'date' } ,
{ key: 'amount', header: 'Amount', editable: true, editor: 'text' },
{
key: 'category',
header: 'Category',
editable: true,
editor: 'dropdown',
editorOptions: {
options: [
{ option: 'Office Supplies', key: 'office' },
{ option: 'Hardware', key: 'hardware' },
{ option: 'Software', key: 'software' },
{ option: 'Travel', key: 'travel' },
],
},
},
{ key: 'description', header: 'Description', editable: true },
{ key: 'reconciled', header: 'OK', editable: true, editor: 'checkbox' },
]}
@cellEdit= ${ ( e : CustomEvent ) = > console . log ( 'cellEdit' , e . detail ) }
2025-06-27 17:50:54 +00:00
.data= ${ [
{
date : '2021-04-01' ,
amount : '2464.65 €' ,
2026-04-07 15:32:10 +00:00
category : 'office' ,
description : 'Printing Paper - STAPLES BREMEN' ,
reconciled : true ,
2025-06-27 17:50:54 +00:00
} ,
{
date: '2021-04-02',
amount: '165.65 €',
2026-04-07 15:32:10 +00:00
category: 'hardware',
description: 'Logitech Mouse - logi.com OnlineShop',
reconciled: false,
2025-06-27 17:50:54 +00:00
},
{
date: '2021-04-03',
amount: '2999,00 €',
2026-04-07 15:32:10 +00:00
category: 'hardware',
description: 'Macbook Pro 16inch - Apple.de OnlineShop',
reconciled: false,
2025-06-27 17:50:54 +00:00
},
{
date: '2021-04-01',
amount: '2464.65 €',
2026-04-07 15:32:10 +00:00
category: 'office',
2025-06-27 17:50:54 +00:00
description: 'Office-Supplies - STAPLES BREMEN',
2026-04-07 15:32:10 +00:00
reconciled: true,
2025-06-27 17:50:54 +00:00
},
{
date: '2021-04-01',
amount: '2464.65 €',
2026-04-07 15:32:10 +00:00
category: 'office',
2025-06-27 17:50:54 +00:00
description: 'Office-Supplies - STAPLES BREMEN',
2026-04-07 15:32:10 +00:00
reconciled: true,
2025-06-27 17:50:54 +00:00
},
]}
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>
2025-09-14 19:57:50 +00:00
<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 } < / d e e s - b a d g e > ` } ,
{ 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"
> < / d e e s - t a b l e >
< / 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"
> < / d e e s - t a b l e >
< / div >
2025-09-16 14:53:59 +00:00
< div class = "demo-section"
@ selectionChange = $ { ( e : CustomEvent ) = > { console . log ( 'Selection changed' , e . detail ) ; } }
@search - changed = $ { ( e : CustomEvent ) = > {
const tbl = document . getElementById ( 'tableFilterSelectDemo' ) as any ;
if ( tbl ) tbl . setFilterText ( e . detail . value ) ;
} }
@search - submit = $ { ( e : CustomEvent ) = > {
const tbl = document . getElementById ( 'tableFilterSelectDemo' ) as any ;
if ( tbl ) tbl . setFilterText ( e . detail . value ) ;
} }
>
< h2 class = "demo-title" > Filtering + Multi - Selection ( New ) < / h2 >
< p class = "demo-description" > Use the search bar to filter rows ; toggle selection via checkboxes . Click headers to sort . < / p >
< dees - searchbar > < / d e e s - s e a r c h b a r >
< div style = "height: 12px" > < / div >
< dees - table
id = "tableFilterSelectDemo"
heading1 = "Inventory (Filter + Select)"
heading2 = "Try typing to filter and selecting multiple rows"
.selectionMode = $ { 'multi' }
.rowKey = $ { 'sku' }
.columns = $ { [
{ key : 'sku' , header : 'SKU' , sortable : true } ,
{ key : 'name' , header : 'Name' , sortable : true } ,
{ key : 'stock' , header : 'Stock' , sortable : true } ,
] }
.data = $ { [
{ sku : 'A-100' , name : 'USB-C Cable' , stock : 120 } ,
{ sku : 'A-101' , name : 'Wireless Mouse' , stock : 55 } ,
{ sku : 'A-102' , name : 'Laptop Stand' , stock : 18 } ,
{ sku : 'B-200' , name : 'Keyboard (ISO)' , stock : 89 } ,
{ sku : 'B-201' , name : 'HDMI Adapter' , stock : 0 } ,
{ sku : 'C-300' , name : 'Webcam 1080p' , stock : 42 } ,
] }
dataName = "items"
> < / d e e s - t a b l e >
< / div >
2025-09-16 15:17:33 +00:00
< div class = "demo-section" >
< h2 class = "demo-title" > Column Filters + Sticky Header ( New ) < / h2 >
< p class = "demo-description" > Per - column quick filters and sticky header with internal scroll . Try filtering the Name column . Uses -- table - max - height var . < / p >
< style >
2026-04-07 15:32:10 +00:00
dees - table [ fixed - height ] { -- table - max - height : 220px ; }
2025-09-16 15:17:33 +00:00
< / style >
< dees - table
heading1 = "Employees"
heading2 = "Quick filter per column + sticky header"
.showColumnFilters = $ { true }
2026-04-07 15:32:10 +00:00
.fixedHeight = $ { true }
2025-09-16 15:17:33 +00:00
.columns = $ { [
{ key : 'name' , header : 'Name' , sortable : true } ,
{ key : 'email' , header : 'Email' , sortable : true } ,
{ key : 'department' , header : 'Department' , sortable : true } ,
] }
.data = $ { [
{ name : 'Alice Johnson' , email : 'alice@corp.com' , department : 'Engineering' } ,
{ name : 'Bob Smith' , email : 'bob@corp.com' , department : 'Sales' } ,
{ name : 'Charlie Davis' , email : 'charlie@corp.com' , department : 'HR' } ,
{ name : 'Diana Martinez' , email : 'diana@corp.com' , department : 'Engineering' } ,
{ name : 'Ethan Brown' , email : 'ethan@corp.com' , department : 'Finance' } ,
{ name : 'Fiona Clark' , email : 'fiona@corp.com' , department : 'Sales' } ,
{ name : 'Grace Lee' , email : 'grace@corp.com' , department : 'Engineering' } ,
{ name : 'Henry Wilson' , email : 'henry@corp.com' , department : 'Marketing' } ,
{ name : 'Irene Walker' , email : 'irene@corp.com' , department : 'Finance' } ,
{ name : 'Jack Turner' , email : 'jack@corp.com' , department : 'Support' } ,
] }
dataName = "employees"
> < / d e e s - t a b l e >
< / div >
2025-09-16 15:46:44 +00:00
< div class = "demo-section"
@ searchRequest = $ { async ( e : CustomEvent ) = > {
const { query } = e . detail || { query : '' } ;
const table = document . getElementById ( 'serverSearchDemo' ) as any ;
const baseData = [
{ id : 1 , name : 'Alice' , city : 'Berlin' , title : 'Engineer' } ,
{ id : 2 , name : 'Bob' , city : 'Paris' , title : 'Designer' } ,
{ id : 3 , name : 'Charlie' , city : 'London' , title : 'Manager' } ,
{ id : 4 , name : 'Diana' , city : 'Madrid' , title : 'Engineer' } ,
{ id : 5 , name : 'Ethan' , city : 'Rome' , title : 'Support' } ,
] ;
// Simulate async request
await new Promise ( ( r ) = > setTimeout ( r , 300 ) ) ;
const q = String ( query || '' ) . toLowerCase ( ) ;
const filtered = q
? baseData . filter ( ( r ) = > Object . values ( r ) . some ( ( v ) = > String ( v ) . toLowerCase ( ) . includes ( q ) ) )
: baseData ;
table . data = filtered ;
} }
>
< h2 class = "demo-title" > Server Search ( New ) < / h2 >
< p class = "demo-description" > Select Server mode , type a query , and watch the table fetch simulated results . < / p >
< dees - table
id = "serverSearchDemo"
heading1 = "People (Server Search)"
heading2 = "Click Search, choose Server mode, and type"
.columns = $ { [
{ key : 'name' , header : 'Name' } ,
{ key : 'city' , header : 'City' } ,
{ key : 'title' , header : 'Title' } ,
] }
.data = $ { [
{ id : 1 , name : 'Alice' , city : 'Berlin' , title : 'Engineer' } ,
{ id : 2 , name : 'Bob' , city : 'Paris' , title : 'Designer' } ,
{ id : 3 , name : 'Charlie' , city : 'London' , title : 'Manager' } ,
{ id : 4 , name : 'Diana' , city : 'Madrid' , title : 'Engineer' } ,
{ id : 5 , name : 'Ethan' , city : 'Rome' , title : 'Support' } ,
] }
dataName = "people"
> < / d e e s - t a b l e >
< / div >
2026-04-07 12:19:59 +00:00
< div class = "demo-section" >
< h2 class = "demo-title" > Multi - Column Sort < / h2 >
< p class = "demo-description" >
Click any column header for a single - column sort . Hold Shift while clicking to add the
column to a multi - sort cascade ( or cycle its direction ) . Right - click any sortable header
to open a menu where you can pin a column to a specific priority slot , remove it , or
clear the cascade .
< / p >
< dees - table
heading1 = "People Directory"
heading2 = "Pre-seeded with department ▲ 1, name ▲ 2"
.sortBy = $ { [
{ key : 'department' , dir : 'asc' } ,
{ key : 'name' , dir : 'asc' } ,
] }
.columns = $ { [
{ key : 'department' , header : 'Department' , sortable : true } ,
{ key : 'name' , header : 'Name' , sortable : true } ,
{ key : 'role' , header : 'Role' , sortable : true } ,
{ key : 'createdAt' , header : 'Created' , sortable : true } ,
{ key : 'location' , header : 'Location' , sortable : true } ,
{ key : 'status' , header : 'Status' , sortable : true } ,
] }
.data = $ { [
{ department : 'R&D' , name : 'Alice Johnson' , role : 'Engineer' , createdAt : '2023-01-12' , location : 'Berlin' , status : 'Active' } ,
{ department : 'R&D' , name : 'Diana Martinez' , role : 'Engineer' , createdAt : '2020-06-30' , location : 'Madrid' , status : 'Active' } ,
{ department : 'R&D' , name : 'Mark Lee' , role : 'Engineer' , createdAt : '2024-03-04' , location : 'Berlin' , status : 'Active' } ,
{ department : 'Design' , name : 'Bob Smith' , role : 'Designer' , createdAt : '2022-11-05' , location : 'Paris' , status : 'Active' } ,
{ department : 'Design' , name : 'Sara Kim' , role : 'Designer' , createdAt : '2021-08-19' , location : 'Paris' , status : 'On Leave' } ,
{ department : 'Ops' , name : 'Charlie Davis' , role : 'Manager' , createdAt : '2021-04-21' , location : 'London' , status : 'On Leave' } ,
{ department : 'Ops' , name : 'Helena Voss' , role : 'SRE' , createdAt : '2023-07-22' , location : 'London' , status : 'Active' } ,
{ department : 'QA' , name : 'Fiona Clark' , role : 'QA' , createdAt : '2022-03-14' , location : 'Vienna' , status : 'Active' } ,
{ department : 'QA' , name : 'Tomás Rivera' , role : 'QA' , createdAt : '2024-01-09' , location : 'Madrid' , status : 'Active' } ,
{ department : 'CS' , name : 'Ethan Brown' , role : 'Support' , createdAt : '2019-09-18' , location : 'Rome' , status : 'Inactive' } ,
] }
> < / d e e s - t a b l e >
< / div >
2025-09-16 16:17:03 +00:00
< div class = "demo-section" >
< h2 class = "demo-title" > Wide Properties + Many Actions < / h2 >
< p class = "demo-description" > A table with many columns and rich actions to stress test layout and sticky Actions . < / p >
< dees - table
heading1 = "People Directory"
heading2 = "Many properties and actions"
.columns = $ { [
{ key : 'id' , header : 'ID' , sortable : true } ,
{ key : 'name' , header : 'Name' , sortable : true } ,
{ key : 'role' , header : 'Role' , sortable : true } ,
{ key : 'department' , header : 'Department' , sortable : true } ,
{ key : 'email' , header : 'Email' } ,
{ key : 'phone' , header : 'Phone' } ,
{ key : 'location' , header : 'Location' , sortable : true } ,
{ key : 'status' , header : 'Status' , sortable : true } ,
{ key : 'createdAt' , header : 'Created' , sortable : true } ,
{ key : 'updatedAt' , header : 'Updated' , sortable : true } ,
{ key : 'lastLogin' , header : 'Last Login' , sortable : true } ,
{ key : 'projects' , header : 'Projects' } ,
{ key : 'tags' , header : 'Tags' } ,
{ key : 'notes' , header : 'Notes' } ,
] }
.data = $ { [
{ id : 1 , name : 'Alice Johnson' , role : 'Engineer' , department : 'R&D' , email : 'alice@corp.com' , phone : '+1 202 555 0111' , location : 'Berlin' , status : 'Active' , createdAt : '2023-01-12' , updatedAt : '2024-05-03' , lastLogin : '2024-10-01' , projects : 5 , tags : 'typescript, ui' , notes : 'Mentor' } ,
{ id : 2 , name : 'Bob Smith' , role : 'Designer' , department : 'Design' , email : 'bob@corp.com' , phone : '+1 202 555 0112' , location : 'Paris' , status : 'Active' , createdAt : '2022-11-05' , updatedAt : '2024-04-10' , lastLogin : '2024-09-28' , projects : 8 , tags : 'figma, brand' , notes : 'Part-time' } ,
{ id : 3 , name : 'Charlie Davis' , role : 'Manager' , department : 'Ops' , email : 'charlie@corp.com' , phone : '+1 202 555 0113' , location : 'London' , status : 'On Leave' , createdAt : '2021-04-21' , updatedAt : '2024-02-15' , lastLogin : '2024-08-12' , projects : 3 , tags : 'sre, leadership' , notes : '' } ,
{ id : 4 , name : 'Diana Martinez' , role : 'Engineer' , department : 'Platform' , email : 'diana@corp.com' , phone : '+1 202 555 0114' , location : 'Madrid' , status : 'Active' , createdAt : '2020-06-30' , updatedAt : '2024-06-25' , lastLogin : '2024-10-02' , projects : 6 , tags : 'node, api' , notes : 'On-call' } ,
{ id : 5 , name : 'Ethan Brown' , role : 'Support' , department : 'CS' , email : 'ethan@corp.com' , phone : '+1 202 555 0115' , location : 'Rome' , status : 'Inactive' , createdAt : '2019-09-18' , updatedAt : '2024-03-09' , lastLogin : '2024-06-19' , projects : 2 , tags : 'zendesk' , notes : 'Rehire' } ,
{ id : 6 , name : 'Fiona Clark' , role : 'QA' , department : 'QA' , email : 'fiona@corp.com' , phone : '+1 202 555 0116' , location : 'Vienna' , status : 'Active' , createdAt : '2022-03-14' , updatedAt : '2024-03-01' , lastLogin : '2024-09-07' , projects : 7 , tags : 'playwright' , notes : '' } ,
] }
.dataActions = $ { [
{ name : 'View' , iconName : 'lucide:eye' , type : [ 'inRow' , 'contextmenu' ] , actionFunc : async ( { item } ) = > { console . log ( 'view' , item ) ; } } ,
{ name : 'Edit' , iconName : 'lucide:edit' , type : [ 'inRow' , 'contextmenu' ] , actionFunc : async ( { item } ) = > { console . log ( 'edit' , item ) ; } } ,
{ name : 'Delete' , iconName : 'lucide:trash' , type : [ 'inRow' , 'contextmenu' ] , actionFunc : async ( { item } ) = > { console . log ( 'delete' , item ) ; } } ,
{ name : 'Message' , iconName : 'lucide:message-square' , type : [ 'inRow' ] , actionFunc : async ( { item } ) = > { console . log ( 'message' , item ) ; } } ,
{ name : 'History' , iconName : 'lucide:clock' , type : [ 'inRow' ] , actionFunc : async ( { item } ) = > { console . log ( 'history' , item ) ; } } ,
{ name : 'Add New' , iconName : 'lucide:plus' , type : [ 'header' ] , actionFunc : async ( { table } ) = > { console . log ( 'add' ) ; } } ,
{ name : 'Export CSV' , iconName : 'lucide:download' , type : [ 'header' ] , actionFunc : async ( { table } ) = > { console . log ( 'export' ) ; } } ,
{ name : 'Bulk Delete' , iconName : 'lucide:trash-2' , type : [ 'footer' ] , actionFunc : async ( { table } ) = > { console . log ( 'bulk delete' ) ; } } ,
] as ITableAction [ ] }
> < / d e e s - t a b l e >
< / div >
< div class = "demo-section" >
< h2 class = "demo-title" > Scrollable Small Height < / h2 >
< p class = "demo-description" > Same as above , but with many items and a small fixed height to force vertical scrolling inside the table . Actions remain visible on the right ; horizontal scroll appears if needed . < / p >
< style >
# scrollSmallHeight { -- table - max - height : 240px ; }
< / style >
< dees - table
id = "scrollSmallHeight"
2026-04-07 15:32:10 +00:00
.fixedHeight = $ { true }
2026-04-07 15:56:55 +00:00
.virtualized = $ { true }
heading1 = "People Directory (Scrollable, Virtualized)"
2025-09-16 16:17:03 +00:00
heading2 = "Forced scrolling with many items"
.columns = $ { [
{ key : 'id' , header : 'ID' , sortable : true } ,
{ key : 'name' , header : 'Name' , sortable : true } ,
{ key : 'role' , header : 'Role' , sortable : true } ,
{ key : 'department' , header : 'Department' , sortable : true } ,
{ key : 'email' , header : 'Email' } ,
{ key : 'phone' , header : 'Phone' } ,
{ key : 'location' , header : 'Location' , sortable : true } ,
{ key : 'status' , header : 'Status' , sortable : true } ,
{ key : 'createdAt' , header : 'Created' , sortable : true } ,
{ key : 'updatedAt' , header : 'Updated' , sortable : true } ,
{ key : 'lastLogin' , header : 'Last Login' , sortable : true } ,
{ key : 'projects' , header : 'Projects' } ,
{ key : 'tags' , header : 'Tags' } ,
{ key : 'notes' , header : 'Notes' } ,
] }
.data = $ { Array.from ( { length : 100 } , ( _ , i ) = > ( {
id : i + 1 ,
name : ` User ${ i + 1 } ` ,
role : [ 'Engineer' , 'Designer' , 'Manager' , 'QA' , 'Support' ] [ i % 5 ] ,
department : [ 'R&D' , 'Design' , 'Ops' , 'QA' , 'CS' ] [ i % 5 ] ,
email : ` user ${ i + 1 } @corp.com ` ,
phone : ` +1 202 555 ${ String ( 1000 + i ) . slice ( - 4 ) } ` ,
location : [ 'Berlin' , 'Paris' , 'London' , 'Madrid' , 'Rome' ] [ i % 5 ] ,
status : [ 'Active' , 'Inactive' , 'On Leave' ] [ i % 3 ] ,
createdAt : ` 2023- ${ String ( ( i % 12 ) + 1 ) . padStart ( 2 , '0' ) } - ${ String ( ( i % 28 ) + 1 ) . padStart ( 2 , '0' ) } ` ,
updatedAt : ` 2024- ${ String ( ( ( i + 3 ) % 12 ) + 1 ) . padStart ( 2 , '0' ) } - ${ String ( ( ( i + 7 ) % 28 ) + 1 ) . padStart ( 2 , '0' ) } ` ,
lastLogin : ` 2024- ${ String ( ( ( i + 6 ) % 12 ) + 1 ) . padStart ( 2 , '0' ) } - ${ String ( ( ( i + 10 ) % 28 ) + 1 ) . padStart ( 2 , '0' ) } ` ,
projects : ( i % 12 ) ,
tags : i % 2 ? 'typescript' : 'design' ,
notes : i % 3 ? '' : 'Note' ,
} ) ) }
. dataActions = $ { [
{ name : 'View' , iconName : 'lucide:eye' , type : [ 'inRow' ] , actionFunc : async ( { item } ) = > { } } ,
{ name : 'Edit' , iconName : 'lucide:edit' , type : [ 'inRow' ] , actionFunc : async ( { item } ) = > { } } ,
{ name : 'Delete' , iconName : 'lucide:trash' , type : [ 'inRow' ] , actionFunc : async ( { item } ) = > { } } ,
] as ITableAction [ ] }
> < / d e e s - t a b l e >
< / div >
2026-04-08 14:51:49 +00:00
< dees - demowrapper .runAfterRender = $ { async ( elementArg : HTMLElement ) = > {
const tableEl = elementArg . querySelector ( '#demoLiveFlash' ) as any ;
if ( ! tableEl ) return ;
// Guard against double-start if runAfterRender fires more than once
// (e.g. across hot-reload cycles).
if ( tableEl . __liveFlashTimerId ) {
window . clearInterval ( tableEl . __liveFlashTimerId ) ;
}
const tick = ( ) = > {
if ( ! Array . isArray ( tableEl . data ) || tableEl . data . length === 0 ) return ;
const next = tableEl . data . map ( ( r : any ) = > ( { . . . r } ) ) ;
const count = 1 + Math . floor ( Math . random ( ) * 3 ) ;
for ( let i = 0 ; i < count ; i ++ ) {
const idx = Math . floor ( Math . random ( ) * next . length ) ;
const delta = + ( ( Math . random ( ) * 2 - 1 ) * 3 ) . toFixed ( 2 ) ;
const newPrice = Math . max ( 1 , + ( next [ idx ] . price + delta ) . toFixed ( 2 ) ) ;
next [ idx ] = {
. . . next [ idx ] ,
price : newPrice ,
change : delta ,
updatedAt : new Date ( ) . toLocaleTimeString ( ) ,
} ;
}
tableEl . data = next ;
} ;
tableEl . __liveFlashTimerId = window . setInterval ( tick , 1500 ) ;
} } >
< div class = "demo-section" >
< h2 class = "demo-title" > Live Updates with Flash Highlighting < / h2 >
< p class = "demo-description" >
Opt - in cell - flash via < code > highlight - updates = "flash" < / code > . The ticker below mutates
random rows every 1.5 s and reassigns < code > . data < / code > . Updated cells briefly flash
amber and fade out . Requires < code > rowKey < / code > ( here < code > "symbol" < / code > ) . Honors
< code > prefers - reduced - motion < / code > . Row selection persists across updates — click a
row , then watch it stay selected as the data churns .
< / p >
< dees - table
id = "demoLiveFlash"
.rowKey = $ { 'symbol' }
highlight-updates = "flash"
.selectionMode = $ { 'multi' }
heading1 = "Live Market Feed"
heading2 = "Flashing cells indicate updated values"
.columns = $ { [
{ key : 'symbol' , header : 'Symbol' , sortable : true } ,
{ key : 'price' , header : 'Price' , sortable : true } ,
{ key : 'change' , header : 'Δ' , sortable : true } ,
{ key : 'updatedAt' , header : 'Updated' } ,
] }
.data = $ { [
{ symbol : 'AAPL' , price : 182.52 , change : 0 , updatedAt : '—' } ,
{ symbol : 'MSFT' , price : 414.18 , change : 0 , updatedAt : '—' } ,
{ symbol : 'GOOG' , price : 168.74 , change : 0 , updatedAt : '—' } ,
{ symbol : 'AMZN' , price : 186.13 , change : 0 , updatedAt : '—' } ,
{ symbol : 'TSLA' , price : 248.50 , change : 0 , updatedAt : '—' } ,
{ symbol : 'NVDA' , price : 877.35 , change : 0 , updatedAt : '—' } ,
{ symbol : 'META' , price : 492.96 , change : 0 , updatedAt : '—' } ,
{ symbol : 'NFLX' , price : 605.88 , change : 0 , updatedAt : '—' } ,
{ symbol : 'AMD' , price : 165.24 , change : 0 , updatedAt : '—' } ,
{ symbol : 'INTC' , price : 42.15 , change : 0 , updatedAt : '—' } ,
] }
> < / d e e s - t a b l e >
< / div >
< / d e e s - d e m o w r a p p e r >
2025-06-27 17:50:54 +00:00
< / div >
2023-09-12 13:42:55 +02:00
< / div >
2025-09-14 19:57:50 +00:00
` ;