@toclocoinc/lattice-grid 1.66.0 → 1.68.0
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 +1 -1
- package/angular/package.json +1 -1
- package/docs/API.html +87 -29
- package/docs/api-detail.html +40 -5
- package/lattice-grid.d.ts +20 -7
- package/lattice-grid.esm.min.js +35 -11
- package/lattice-grid.min.cjs +35 -11
- package/lattice-grid.min.js +35 -11
- package/modules/ai.d.ts +1 -1
- package/modules/ai.esm.min.js +3 -3
- package/modules/ai.min.cjs +3 -3
- package/modules/ai.min.js +3 -3
- package/modules/angular.d.ts +1 -1
- package/modules/angular.esm.min.js +3 -3
- package/modules/angular.min.cjs +3 -3
- package/modules/angular.min.js +3 -3
- package/modules/chart-alluvial.d.ts +1 -1
- package/modules/chart-alluvial.esm.min.js +1 -1
- package/modules/chart-alluvial.min.cjs +1 -1
- package/modules/chart-alluvial.min.js +1 -1
- package/modules/chart-arc.d.ts +1 -1
- package/modules/chart-arc.esm.min.js +1 -1
- package/modules/chart-arc.min.cjs +1 -1
- package/modules/chart-arc.min.js +1 -1
- package/modules/chart-bubblemap.d.ts +1 -1
- package/modules/chart-bubblemap.esm.min.js +1 -1
- package/modules/chart-bubblemap.min.cjs +1 -1
- package/modules/chart-bubblemap.min.js +1 -1
- package/modules/chart-bump.d.ts +1 -1
- package/modules/chart-bump.esm.min.js +1 -1
- package/modules/chart-bump.min.cjs +1 -1
- package/modules/chart-bump.min.js +1 -1
- package/modules/chart-calendar.d.ts +1 -1
- package/modules/chart-calendar.esm.min.js +1 -1
- package/modules/chart-calendar.min.cjs +1 -1
- package/modules/chart-calendar.min.js +1 -1
- package/modules/chart-decomposition.d.ts +1 -1
- package/modules/chart-decomposition.esm.min.js +1 -1
- package/modules/chart-decomposition.min.cjs +1 -1
- package/modules/chart-decomposition.min.js +1 -1
- package/modules/chart-diverging.d.ts +1 -1
- package/modules/chart-diverging.esm.min.js +1 -1
- package/modules/chart-diverging.min.cjs +1 -1
- package/modules/chart-diverging.min.js +1 -1
- package/modules/chart-dumbbell.d.ts +1 -1
- package/modules/chart-dumbbell.esm.min.js +1 -1
- package/modules/chart-dumbbell.min.cjs +1 -1
- package/modules/chart-dumbbell.min.js +1 -1
- package/modules/chart-fan.d.ts +1 -1
- package/modules/chart-fan.esm.min.js +1 -1
- package/modules/chart-fan.min.cjs +1 -1
- package/modules/chart-fan.min.js +1 -1
- package/modules/chart-hexbin.d.ts +1 -1
- package/modules/chart-hexbin.esm.min.js +1 -1
- package/modules/chart-hexbin.min.cjs +1 -1
- package/modules/chart-hexbin.min.js +1 -1
- package/modules/chart-hexmap.d.ts +1 -1
- package/modules/chart-hexmap.esm.min.js +1 -1
- package/modules/chart-hexmap.min.cjs +1 -1
- package/modules/chart-hexmap.min.js +1 -1
- package/modules/chart-icicle.d.ts +1 -1
- package/modules/chart-icicle.esm.min.js +1 -1
- package/modules/chart-icicle.min.cjs +1 -1
- package/modules/chart-icicle.min.js +1 -1
- package/modules/chart-markermap.d.ts +1 -1
- package/modules/chart-markermap.esm.min.js +1 -1
- package/modules/chart-markermap.min.cjs +1 -1
- package/modules/chart-markermap.min.js +1 -1
- package/modules/chart-parallel.d.ts +1 -1
- package/modules/chart-parallel.esm.min.js +1 -1
- package/modules/chart-parallel.min.cjs +1 -1
- package/modules/chart-parallel.min.js +1 -1
- package/modules/chart-ridgeline.d.ts +1 -1
- package/modules/chart-ridgeline.esm.min.js +1 -1
- package/modules/chart-ridgeline.min.cjs +1 -1
- package/modules/chart-ridgeline.min.js +1 -1
- package/modules/chart-roc.d.ts +1 -1
- package/modules/chart-roc.esm.min.js +1 -1
- package/modules/chart-roc.min.cjs +1 -1
- package/modules/chart-roc.min.js +1 -1
- package/modules/chart-slope.d.ts +1 -1
- package/modules/chart-slope.esm.min.js +1 -1
- package/modules/chart-slope.min.cjs +1 -1
- package/modules/chart-slope.min.js +1 -1
- package/modules/chart-splom.d.ts +1 -1
- package/modules/chart-splom.esm.min.js +1 -1
- package/modules/chart-splom.min.cjs +1 -1
- package/modules/chart-splom.min.js +1 -1
- package/modules/chart-waffle.d.ts +1 -1
- package/modules/chart-waffle.esm.min.js +1 -1
- package/modules/chart-waffle.min.cjs +1 -1
- package/modules/chart-waffle.min.js +1 -1
- package/modules/charts.d.ts +1 -1
- package/modules/charts.esm.min.js +1376 -1249
- package/modules/charts.min.cjs +1376 -1249
- package/modules/charts.min.js +1376 -1249
- package/modules/data-router.d.ts +8 -3
- package/modules/data-router.esm.min.js +229 -11
- package/modules/data-router.min.cjs +229 -11
- package/modules/data-router.min.js +229 -11
- package/modules/devtools.d.ts +1 -1
- package/modules/devtools.esm.min.js +1 -1
- package/modules/devtools.min.cjs +1 -1
- package/modules/devtools.min.js +1 -1
- package/modules/dhtmlx-compat.d.ts +1 -1
- package/modules/dhtmlx-compat.esm.min.js +3 -3
- package/modules/dhtmlx-compat.min.cjs +3 -3
- package/modules/dhtmlx-compat.min.js +3 -3
- package/modules/gantt.d.ts +8 -3
- package/modules/gantt.esm.min.js +56 -8
- package/modules/gantt.min.cjs +56 -8
- package/modules/gantt.min.js +56 -8
- package/modules/geo-europe-nuts.d.ts +1 -1
- package/modules/geo-europe-nuts.esm.min.js +1 -1
- package/modules/geo-uk.d.ts +1 -1
- package/modules/geo-uk.esm.min.js +1 -1
- package/modules/geo-us-states.d.ts +1 -1
- package/modules/geo-us-states.esm.min.js +1 -1
- package/modules/geo-world-110m.d.ts +1 -1
- package/modules/geo-world-110m.esm.min.js +1 -1
- package/modules/geo-world-50m.d.ts +1 -1
- package/modules/geo-world-50m.esm.min.js +1 -1
- package/modules/htmx.d.ts +1 -1
- package/modules/htmx.esm.min.js +35 -11
- package/modules/htmx.min.cjs +35 -11
- package/modules/htmx.min.js +35 -11
- package/modules/kanban.d.ts +10 -3
- package/modules/kanban.esm.min.js +24 -4
- package/modules/kanban.min.cjs +24 -4
- package/modules/kanban.min.js +24 -4
- package/modules/kpi.d.ts +35 -10
- package/modules/kpi.esm.min.js +55 -7
- package/modules/kpi.min.cjs +55 -7
- package/modules/kpi.min.js +55 -7
- package/modules/layout.d.ts +1 -1
- package/modules/layout.esm.min.js +3 -3
- package/modules/layout.min.cjs +3 -3
- package/modules/layout.min.js +3 -3
- package/modules/mock-socket.d.ts +1 -1
- package/modules/mock-socket.esm.min.js +1 -1
- package/modules/mock-socket.min.cjs +1 -1
- package/modules/mock-socket.min.js +1 -1
- package/modules/react.d.ts +1 -1
- package/modules/react.esm.min.js +3 -3
- package/modules/react.min.cjs +3 -3
- package/modules/react.min.js +3 -3
- package/modules/svelte.d.ts +1 -1
- package/modules/svelte.esm.min.js +3 -3
- package/modules/svelte.min.cjs +3 -3
- package/modules/svelte.min.js +3 -3
- package/modules/tabs.d.ts +1 -1
- package/modules/tabs.esm.min.js +13 -14
- package/modules/tabs.min.cjs +13 -14
- package/modules/tabs.min.js +13 -14
- package/modules/vue.d.ts +1 -1
- package/modules/vue.esm.min.js +3 -3
- package/modules/vue.min.cjs +3 -3
- package/modules/vue.min.js +3 -3
- package/modules/webcomponent.d.ts +1 -1
- package/modules/webcomponent.esm.min.js +35 -11
- package/modules/webcomponent.min.cjs +35 -11
- package/modules/webcomponent.min.js +35 -11
- package/package.json +1 -1
package/modules/kanban.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.68.0, kanban module type declarations
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -215,7 +215,13 @@ interface KanbanSla {
|
|
|
215
215
|
interface KanbanConfig {
|
|
216
216
|
rows?: KanbanRow[];
|
|
217
217
|
grid?: unknown;
|
|
218
|
-
|
|
218
|
+
/**
|
|
219
|
+
* Card identity (a field or fn, returning a string or number); default
|
|
220
|
+
* 'id'. Composite (`string[]`) keys are core-grid-only: a board keys its
|
|
221
|
+
* own card identity from one value, so there is nothing for an array to
|
|
222
|
+
* join into here.
|
|
223
|
+
*/
|
|
224
|
+
rowKey?: string | ((row: KanbanRow) => string | number);
|
|
219
225
|
columnProperty?: string;
|
|
220
226
|
columns?: KanbanColumnDef[];
|
|
221
227
|
columnOrder?: string[];
|
|
@@ -376,7 +382,8 @@ interface KanbanFilters {
|
|
|
376
382
|
*/
|
|
377
383
|
interface Kanban {
|
|
378
384
|
readonly el: unknown | null;
|
|
379
|
-
|
|
385
|
+
/** The resolved card identity; see `KanbanConfig.rowKey`. */
|
|
386
|
+
readonly rowKey: string | ((row: KanbanRow) => string | number);
|
|
380
387
|
rows: KanbanRows;
|
|
381
388
|
/** The card-aging / SLA monitor, present only when a `sla` config was supplied. */
|
|
382
389
|
sla?: KanbanSla;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.68.0, kanban module
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -52,12 +52,12 @@ Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){r
|
|
|
52
52
|
Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
|
|
53
53
|
Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
|
|
54
54
|
Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
|
|
55
|
-
const STAMPED_VERSION="1.
|
|
55
|
+
const STAMPED_VERSION="1.68.0";
|
|
56
56
|
async function resolveVersion(){
|
|
57
57
|
if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
|
|
58
58
|
return STAMPED_VERSION;
|
|
59
59
|
}
|
|
60
|
-
const VERSION="1.
|
|
60
|
+
const VERSION="1.68.0";
|
|
61
61
|
const warned=new Set();
|
|
62
62
|
const WARNED_LIMIT=2000;
|
|
63
63
|
function rememberWarned(key){
|
|
@@ -444,8 +444,28 @@ if(isFunction(accessor))return accessor;
|
|
|
444
444
|
if(typeof accessor==='string')return(row)=>getPath(row,accessor);
|
|
445
445
|
return()=>undefined;
|
|
446
446
|
}
|
|
447
|
+
function rowKeyTypeName(v){
|
|
448
|
+
if(Array.isArray(v))return'array';
|
|
449
|
+
if(v===null)return'null';
|
|
450
|
+
return typeof v;
|
|
451
|
+
}
|
|
447
452
|
function keyFn(rowKey){
|
|
448
|
-
if(
|
|
453
|
+
if(rowKey!==undefined&&typeof rowKey!=='function'
|
|
454
|
+
&&!(typeof rowKey==='string'&&rowKey.length>0)){
|
|
455
|
+
throw new Error(
|
|
456
|
+
'lattice-kanban: rowKey must be a property name or a function; composite keys are not supported on boards.',
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
if(isFunction(rowKey)){
|
|
460
|
+
return(row)=>{
|
|
461
|
+
const key=rowKey(row);
|
|
462
|
+
if(typeof key==='string')return key;
|
|
463
|
+
if(typeof key==='number'&&Number.isFinite(key))return key;
|
|
464
|
+
throw new Error(
|
|
465
|
+
`lattice-kanban: rowKey function must return a string or number; got ${rowKeyTypeName(key)}.`,
|
|
466
|
+
);
|
|
467
|
+
};
|
|
468
|
+
}
|
|
449
469
|
const path=typeof rowKey==='string'?rowKey:'id';
|
|
450
470
|
return(row)=>getPath(row,path);
|
|
451
471
|
}
|
package/modules/kanban.min.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.68.0, kanban module
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -54,12 +54,12 @@ Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){r
|
|
|
54
54
|
Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
|
|
55
55
|
Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
|
|
56
56
|
Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
|
|
57
|
-
const STAMPED_VERSION="1.
|
|
57
|
+
const STAMPED_VERSION="1.68.0";
|
|
58
58
|
async function resolveVersion(){
|
|
59
59
|
if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
|
|
60
60
|
return STAMPED_VERSION;
|
|
61
61
|
}
|
|
62
|
-
const VERSION="1.
|
|
62
|
+
const VERSION="1.68.0";
|
|
63
63
|
const warned=new Set();
|
|
64
64
|
const WARNED_LIMIT=2000;
|
|
65
65
|
function rememberWarned(key){
|
|
@@ -446,8 +446,28 @@ if(isFunction(accessor))return accessor;
|
|
|
446
446
|
if(typeof accessor==='string')return(row)=>getPath(row,accessor);
|
|
447
447
|
return()=>undefined;
|
|
448
448
|
}
|
|
449
|
+
function rowKeyTypeName(v){
|
|
450
|
+
if(Array.isArray(v))return'array';
|
|
451
|
+
if(v===null)return'null';
|
|
452
|
+
return typeof v;
|
|
453
|
+
}
|
|
449
454
|
function keyFn(rowKey){
|
|
450
|
-
if(
|
|
455
|
+
if(rowKey!==undefined&&typeof rowKey!=='function'
|
|
456
|
+
&&!(typeof rowKey==='string'&&rowKey.length>0)){
|
|
457
|
+
throw new Error(
|
|
458
|
+
'lattice-kanban: rowKey must be a property name or a function; composite keys are not supported on boards.',
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
if(isFunction(rowKey)){
|
|
462
|
+
return(row)=>{
|
|
463
|
+
const key=rowKey(row);
|
|
464
|
+
if(typeof key==='string')return key;
|
|
465
|
+
if(typeof key==='number'&&Number.isFinite(key))return key;
|
|
466
|
+
throw new Error(
|
|
467
|
+
`lattice-kanban: rowKey function must return a string or number; got ${rowKeyTypeName(key)}.`,
|
|
468
|
+
);
|
|
469
|
+
};
|
|
470
|
+
}
|
|
451
471
|
const path=typeof rowKey==='string'?rowKey:'id';
|
|
452
472
|
return(row)=>getPath(row,path);
|
|
453
473
|
}
|
package/modules/kanban.min.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.68.0, kanban module
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -54,12 +54,12 @@ Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){r
|
|
|
54
54
|
Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
|
|
55
55
|
Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
|
|
56
56
|
Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
|
|
57
|
-
const STAMPED_VERSION="1.
|
|
57
|
+
const STAMPED_VERSION="1.68.0";
|
|
58
58
|
async function resolveVersion(){
|
|
59
59
|
if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
|
|
60
60
|
return STAMPED_VERSION;
|
|
61
61
|
}
|
|
62
|
-
const VERSION="1.
|
|
62
|
+
const VERSION="1.68.0";
|
|
63
63
|
const warned=new Set();
|
|
64
64
|
const WARNED_LIMIT=2000;
|
|
65
65
|
function rememberWarned(key){
|
|
@@ -446,8 +446,28 @@ if(isFunction(accessor))return accessor;
|
|
|
446
446
|
if(typeof accessor==='string')return(row)=>getPath(row,accessor);
|
|
447
447
|
return()=>undefined;
|
|
448
448
|
}
|
|
449
|
+
function rowKeyTypeName(v){
|
|
450
|
+
if(Array.isArray(v))return'array';
|
|
451
|
+
if(v===null)return'null';
|
|
452
|
+
return typeof v;
|
|
453
|
+
}
|
|
449
454
|
function keyFn(rowKey){
|
|
450
|
-
if(
|
|
455
|
+
if(rowKey!==undefined&&typeof rowKey!=='function'
|
|
456
|
+
&&!(typeof rowKey==='string'&&rowKey.length>0)){
|
|
457
|
+
throw new Error(
|
|
458
|
+
'lattice-kanban: rowKey must be a property name or a function; composite keys are not supported on boards.',
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
if(isFunction(rowKey)){
|
|
462
|
+
return(row)=>{
|
|
463
|
+
const key=rowKey(row);
|
|
464
|
+
if(typeof key==='string')return key;
|
|
465
|
+
if(typeof key==='number'&&Number.isFinite(key))return key;
|
|
466
|
+
throw new Error(
|
|
467
|
+
`lattice-kanban: rowKey function must return a string or number; got ${rowKeyTypeName(key)}.`,
|
|
468
|
+
);
|
|
469
|
+
};
|
|
470
|
+
}
|
|
451
471
|
const path=typeof rowKey==='string'?rowKey:'id';
|
|
452
472
|
return(row)=>getPath(row,path);
|
|
453
473
|
}
|
package/modules/kpi.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.68.0, kpi module type declarations
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -60,6 +60,15 @@ interface KPIStatTile {
|
|
|
60
60
|
target?: number;
|
|
61
61
|
/** A baseline the tile's delta is measured against. */
|
|
62
62
|
baseline?: number;
|
|
63
|
+
/**
|
|
64
|
+
* What the movement line prints against `baseline` (F-FRED-G): `'absolute'` the difference alone, `'relative'` the
|
|
65
|
+
* percentage alone, `'both'` (the default, unchanged) both together. A
|
|
66
|
+
* rate series (4.10 vs 4.30) makes the percentage a percent-of-a-percent
|
|
67
|
+
* and meaningless, so `'absolute'` is how a host keeps the line without
|
|
68
|
+
* it. The arrow and its colour follow the sign of the difference either
|
|
69
|
+
* way.
|
|
70
|
+
*/
|
|
71
|
+
delta?: 'absolute' | 'relative' | 'both';
|
|
63
72
|
/** Threshold bands, either two cut points or an explicit band list. */
|
|
64
73
|
thresholds?: KPIThresholds;
|
|
65
74
|
/** Explicit status bands (an alternative to `thresholds`). */
|
|
@@ -112,12 +121,15 @@ type KPITile = KPIStatTile | KPIClockTile;
|
|
|
112
121
|
* of top-level items that expand to the indicators beneath them, each parent
|
|
113
122
|
* highlighted with the worst status below it.
|
|
114
123
|
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
124
|
+
* `tree` is an opt-in: omitted or `false`, the panel is
|
|
125
|
+
* flat whatever its tile ids look like, and a dotted id seen with `tree`
|
|
126
|
+
* unset is reported once rather than silently turned into a hierarchy. Given
|
|
127
|
+
* any object (`{}` included), the shape is declared with `path` or
|
|
128
|
+
* `parentKey` — the same two shapes the grid's tree data and the tree-select
|
|
129
|
+
* editor take — over the **tile specs**, not the rows. With neither declared,
|
|
130
|
+
* one is derived by splitting the tile ids on `separator`, so
|
|
131
|
+
* `system.compute.cpu` files itself under Compute under System. A panel
|
|
132
|
+
* whose ids carry no separator stays flat even with `tree` set.
|
|
121
133
|
*
|
|
122
134
|
* A tile's `field` is never a source: a dot there already means a nested
|
|
123
135
|
* object property.
|
|
@@ -209,6 +221,8 @@ interface KPITileModel {
|
|
|
209
221
|
delta: number | null;
|
|
210
222
|
deltaPercent: number | null;
|
|
211
223
|
deltaFormatted?: string;
|
|
224
|
+
/** What the movement line prints; see `KPIStatTile.delta`. Always present once `baseline` is. */
|
|
225
|
+
deltaMode?: 'absolute' | 'relative' | 'both';
|
|
212
226
|
count: number;
|
|
213
227
|
sparkline: number[] | null;
|
|
214
228
|
}
|
|
@@ -224,7 +238,13 @@ interface KPIEvent {
|
|
|
224
238
|
interface KPIConfig {
|
|
225
239
|
rows?: KPIRow[];
|
|
226
240
|
grid?: unknown;
|
|
227
|
-
|
|
241
|
+
/**
|
|
242
|
+
* Row identity (a field or fn, returning a string or number); default
|
|
243
|
+
* 'id'. Composite (`string[]`) keys are core-grid-only: a panel keys its
|
|
244
|
+
* own tile identity from one value, so there is nothing for an array to
|
|
245
|
+
* join into here.
|
|
246
|
+
*/
|
|
247
|
+
rowKey?: string | ((row: KPIRow) => string | number);
|
|
228
248
|
/**
|
|
229
249
|
* Extra columns of the bound `grid` to project onto the rows a tile `filter`
|
|
230
250
|
* sees, beyond the fields the tiles themselves declare. A grid-bound panel
|
|
@@ -243,7 +263,11 @@ interface KPIConfig {
|
|
|
243
263
|
* on a stat tile, which takes its own `format.locale`.
|
|
244
264
|
*/
|
|
245
265
|
locale?: string;
|
|
246
|
-
/**
|
|
266
|
+
/**
|
|
267
|
+
* Arrange the tiles as a hierarchy; unset or `false` keeps the panel flat.
|
|
268
|
+
* Opt-in: a dotted tile id is not a hierarchy until
|
|
269
|
+
* `tree` is set, and warns once while it is not.
|
|
270
|
+
*/
|
|
247
271
|
tree?: KPITreeConfig | false;
|
|
248
272
|
/**
|
|
249
273
|
* The catalogue the panel's own text is read from. A panel routinely has no
|
|
@@ -274,7 +298,8 @@ interface KPIRows {
|
|
|
274
298
|
*/
|
|
275
299
|
interface KPI {
|
|
276
300
|
readonly el: unknown | null;
|
|
277
|
-
|
|
301
|
+
/** The resolved row identity; see `KPIConfig.rowKey`. */
|
|
302
|
+
readonly rowKey: string | ((row: KPIRow) => string | number);
|
|
278
303
|
/** Whether the panel renders as a hierarchy rather than a flat tile grid. */
|
|
279
304
|
readonly tree: boolean;
|
|
280
305
|
rows: KPIRows;
|
package/modules/kpi.esm.min.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.68.0, kpi module
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -52,12 +52,12 @@ Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){r
|
|
|
52
52
|
Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
|
|
53
53
|
Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
|
|
54
54
|
Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
|
|
55
|
-
const STAMPED_VERSION="1.
|
|
55
|
+
const STAMPED_VERSION="1.68.0";
|
|
56
56
|
async function resolveVersion(){
|
|
57
57
|
if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
|
|
58
58
|
return STAMPED_VERSION;
|
|
59
59
|
}
|
|
60
|
-
const VERSION="1.
|
|
60
|
+
const VERSION="1.68.0";
|
|
61
61
|
const warned=new Set();
|
|
62
62
|
const WARNED_LIMIT=2000;
|
|
63
63
|
function rememberWarned(key){
|
|
@@ -825,7 +825,15 @@ const rank=Math.max(SEVERITY[a]||0,SEVERITY[b]||0);
|
|
|
825
825
|
return BY_RANK[rank];
|
|
826
826
|
}
|
|
827
827
|
function resolveHierarchy(config,tiles){
|
|
828
|
-
if(
|
|
828
|
+
if(!tiles.length)return null;
|
|
829
|
+
if(config===false)return null;
|
|
830
|
+
if(config===undefined||config===null){
|
|
831
|
+
if(tiles.some((t)=>t.id.includes(DEFAULT_SEPARATOR))){
|
|
832
|
+
warnOnce('kpi:tree:dotted-id',
|
|
833
|
+
'kpi: tile ids contain dots; set `tree` to render them as a hierarchy.');
|
|
834
|
+
}
|
|
835
|
+
return null;
|
|
836
|
+
}
|
|
829
837
|
const cfg=isObject(config)?config:{};
|
|
830
838
|
const order=tiles.map((_,i)=>i);
|
|
831
839
|
const keyOf=(physical)=>tiles[physical].id;
|
|
@@ -1184,14 +1192,20 @@ return node;
|
|
|
1184
1192
|
function deltaNode(doc,fig,t){
|
|
1185
1193
|
const dir=t.delta>0?'up':(t.delta<0?'down':'flat');
|
|
1186
1194
|
const arrow=t.delta>0?'▲':(t.delta<0?'▼':'■');
|
|
1195
|
+
const abs=t.deltaFormatted??t.delta;
|
|
1187
1196
|
const pct=t.deltaPercent===null||t.deltaPercent===undefined
|
|
1188
|
-
?
|
|
1197
|
+
?null:`${(t.deltaPercent*100).toFixed(1)}%`;
|
|
1198
|
+
const mode=t.deltaMode||'both';
|
|
1199
|
+
let text;
|
|
1200
|
+
if(mode==='absolute'||pct===null)text=`${arrow} ${abs}`;
|
|
1201
|
+
else if(mode==='relative')text=`${arrow} ${pct}`;
|
|
1202
|
+
else text=`${arrow} ${abs} (${pct})`;
|
|
1189
1203
|
const node=childByClass(fig,`${NS}__delta`)||div(doc,`${NS}__delta`);
|
|
1190
1204
|
for(const d of['up','down','flat']){
|
|
1191
1205
|
if(d!==dir)node.classList.remove(`${NS}__delta--${d}`);
|
|
1192
1206
|
}
|
|
1193
1207
|
node.classList.add(`${NS}__delta--${dir}`);
|
|
1194
|
-
setText(node
|
|
1208
|
+
setText(node,text);
|
|
1195
1209
|
return node;
|
|
1196
1210
|
}
|
|
1197
1211
|
function sparkNode(doc,fig,t){
|
|
@@ -5843,6 +5857,7 @@ const readClock=__m7["readClock"];
|
|
|
5843
5857
|
const KPI_EVENTS=Object.freeze([
|
|
5844
5858
|
'tile:click','tile:dblclick','tile:contextmenu','node:toggle','change',
|
|
5845
5859
|
]);
|
|
5860
|
+
const DELTA_MODES=Object.freeze(['absolute','relative','both']);
|
|
5846
5861
|
const GRID_FOLLOW_EVENTS=Object.freeze([
|
|
5847
5862
|
'rows:changed','filter:changed','sort:changed','cell:changed','model:changed',
|
|
5848
5863
|
'stream:chunk','stream:evicted',
|
|
@@ -5854,8 +5869,30 @@ onTileContextMenu:'tile:contextmenu',
|
|
|
5854
5869
|
onNodeToggle:'node:toggle',
|
|
5855
5870
|
onChange:'change',
|
|
5856
5871
|
});
|
|
5872
|
+
function rowKeyTypeName(v){
|
|
5873
|
+
if(Array.isArray(v))return'array';
|
|
5874
|
+
if(v===null)return'null';
|
|
5875
|
+
return typeof v;
|
|
5876
|
+
}
|
|
5877
|
+
function assertRowKeyShape(rowKey){
|
|
5878
|
+
if(rowKey===undefined)return;
|
|
5879
|
+
if(typeof rowKey==='string'&&rowKey.length>0)return;
|
|
5880
|
+
if(typeof rowKey==='function')return;
|
|
5881
|
+
throw new Error(
|
|
5882
|
+
'lattice-kpi: rowKey must be a property name or a function; composite keys are not supported on tiles.',
|
|
5883
|
+
);
|
|
5884
|
+
}
|
|
5857
5885
|
function keyFn(rowKey){
|
|
5858
|
-
if(isFunction(rowKey))
|
|
5886
|
+
if(isFunction(rowKey)){
|
|
5887
|
+
return(row)=>{
|
|
5888
|
+
const key=rowKey(row);
|
|
5889
|
+
if(typeof key==='string')return key;
|
|
5890
|
+
if(typeof key==='number'&&Number.isFinite(key))return key;
|
|
5891
|
+
throw new Error(
|
|
5892
|
+
`lattice-kpi: rowKey function must return a string or number; got ${rowKeyTypeName(key)}.`,
|
|
5893
|
+
);
|
|
5894
|
+
};
|
|
5895
|
+
}
|
|
5859
5896
|
const get=pathGetter(typeof rowKey==='string'&&rowKey?rowKey:'id');
|
|
5860
5897
|
return(row)=>get(row);
|
|
5861
5898
|
}
|
|
@@ -5886,12 +5923,20 @@ format:spec.format,
|
|
|
5886
5923
|
target:spec.target,
|
|
5887
5924
|
barBounds:barBounds(spec),
|
|
5888
5925
|
baseline:spec.baseline,
|
|
5926
|
+
deltaMode:resolveDeltaMode(spec.delta,id),
|
|
5889
5927
|
spark:normaliseSpark(spec.sparkline),
|
|
5890
5928
|
acc,
|
|
5891
5929
|
members:0,
|
|
5892
5930
|
noColumn:false,
|
|
5893
5931
|
};
|
|
5894
5932
|
}
|
|
5933
|
+
function resolveDeltaMode(raw,id){
|
|
5934
|
+
if(raw===undefined)return'both';
|
|
5935
|
+
if(DELTA_MODES.includes(raw))return raw;
|
|
5936
|
+
warnOnce(`kpi:delta:${id}`,
|
|
5937
|
+
`kpi: tile "${id}" has delta: ${JSON.stringify(raw)}; expected one of ${DELTA_MODES.join(', ')}. Falling back to 'both'.`);
|
|
5938
|
+
return'both';
|
|
5939
|
+
}
|
|
5895
5940
|
function normaliseSpark(s){
|
|
5896
5941
|
if(!s)return null;
|
|
5897
5942
|
if(typeof s==='string')return{x:undefined,y:accessorFor(s)};
|
|
@@ -6036,6 +6081,7 @@ return rows;
|
|
|
6036
6081
|
}
|
|
6037
6082
|
function createKPI(el,config={}){
|
|
6038
6083
|
const cfg=isObject(config)?config:{};
|
|
6084
|
+
assertRowKeyShape(cfg.rowKey);
|
|
6039
6085
|
const gridBound=!!cfg.grid&&!Array.isArray(cfg.rows);
|
|
6040
6086
|
const key=gridBound?keyFn('__kpiKey'):keyFn(cfg.rowKey);
|
|
6041
6087
|
const nullText=typeof cfg.nullText==='string'?cfg.nullText:'—';
|
|
@@ -6137,6 +6183,7 @@ baseline:undefined,
|
|
|
6137
6183
|
delta:null,
|
|
6138
6184
|
deltaPercent:null,
|
|
6139
6185
|
deltaFormatted:undefined,
|
|
6186
|
+
deltaMode:undefined,
|
|
6140
6187
|
count:0,
|
|
6141
6188
|
sparkline:null,
|
|
6142
6189
|
bar:null,
|
|
@@ -6174,6 +6221,7 @@ baseline:t.baseline,
|
|
|
6174
6221
|
delta,
|
|
6175
6222
|
deltaPercent,
|
|
6176
6223
|
deltaFormatted,
|
|
6224
|
+
deltaMode:t.deltaMode,
|
|
6177
6225
|
count:t.members,
|
|
6178
6226
|
sparkline:sparkFor(t),
|
|
6179
6227
|
bar:t.barBounds
|
package/modules/kpi.min.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.68.0, kpi module
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -54,12 +54,12 @@ Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){r
|
|
|
54
54
|
Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
|
|
55
55
|
Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
|
|
56
56
|
Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
|
|
57
|
-
const STAMPED_VERSION="1.
|
|
57
|
+
const STAMPED_VERSION="1.68.0";
|
|
58
58
|
async function resolveVersion(){
|
|
59
59
|
if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
|
|
60
60
|
return STAMPED_VERSION;
|
|
61
61
|
}
|
|
62
|
-
const VERSION="1.
|
|
62
|
+
const VERSION="1.68.0";
|
|
63
63
|
const warned=new Set();
|
|
64
64
|
const WARNED_LIMIT=2000;
|
|
65
65
|
function rememberWarned(key){
|
|
@@ -827,7 +827,15 @@ const rank=Math.max(SEVERITY[a]||0,SEVERITY[b]||0);
|
|
|
827
827
|
return BY_RANK[rank];
|
|
828
828
|
}
|
|
829
829
|
function resolveHierarchy(config,tiles){
|
|
830
|
-
if(
|
|
830
|
+
if(!tiles.length)return null;
|
|
831
|
+
if(config===false)return null;
|
|
832
|
+
if(config===undefined||config===null){
|
|
833
|
+
if(tiles.some((t)=>t.id.includes(DEFAULT_SEPARATOR))){
|
|
834
|
+
warnOnce('kpi:tree:dotted-id',
|
|
835
|
+
'kpi: tile ids contain dots; set `tree` to render them as a hierarchy.');
|
|
836
|
+
}
|
|
837
|
+
return null;
|
|
838
|
+
}
|
|
831
839
|
const cfg=isObject(config)?config:{};
|
|
832
840
|
const order=tiles.map((_,i)=>i);
|
|
833
841
|
const keyOf=(physical)=>tiles[physical].id;
|
|
@@ -1186,14 +1194,20 @@ return node;
|
|
|
1186
1194
|
function deltaNode(doc,fig,t){
|
|
1187
1195
|
const dir=t.delta>0?'up':(t.delta<0?'down':'flat');
|
|
1188
1196
|
const arrow=t.delta>0?'▲':(t.delta<0?'▼':'■');
|
|
1197
|
+
const abs=t.deltaFormatted??t.delta;
|
|
1189
1198
|
const pct=t.deltaPercent===null||t.deltaPercent===undefined
|
|
1190
|
-
?
|
|
1199
|
+
?null:`${(t.deltaPercent*100).toFixed(1)}%`;
|
|
1200
|
+
const mode=t.deltaMode||'both';
|
|
1201
|
+
let text;
|
|
1202
|
+
if(mode==='absolute'||pct===null)text=`${arrow} ${abs}`;
|
|
1203
|
+
else if(mode==='relative')text=`${arrow} ${pct}`;
|
|
1204
|
+
else text=`${arrow} ${abs} (${pct})`;
|
|
1191
1205
|
const node=childByClass(fig,`${NS}__delta`)||div(doc,`${NS}__delta`);
|
|
1192
1206
|
for(const d of['up','down','flat']){
|
|
1193
1207
|
if(d!==dir)node.classList.remove(`${NS}__delta--${d}`);
|
|
1194
1208
|
}
|
|
1195
1209
|
node.classList.add(`${NS}__delta--${dir}`);
|
|
1196
|
-
setText(node
|
|
1210
|
+
setText(node,text);
|
|
1197
1211
|
return node;
|
|
1198
1212
|
}
|
|
1199
1213
|
function sparkNode(doc,fig,t){
|
|
@@ -5845,6 +5859,7 @@ const readClock=__m7["readClock"];
|
|
|
5845
5859
|
const KPI_EVENTS=Object.freeze([
|
|
5846
5860
|
'tile:click','tile:dblclick','tile:contextmenu','node:toggle','change',
|
|
5847
5861
|
]);
|
|
5862
|
+
const DELTA_MODES=Object.freeze(['absolute','relative','both']);
|
|
5848
5863
|
const GRID_FOLLOW_EVENTS=Object.freeze([
|
|
5849
5864
|
'rows:changed','filter:changed','sort:changed','cell:changed','model:changed',
|
|
5850
5865
|
'stream:chunk','stream:evicted',
|
|
@@ -5856,8 +5871,30 @@ onTileContextMenu:'tile:contextmenu',
|
|
|
5856
5871
|
onNodeToggle:'node:toggle',
|
|
5857
5872
|
onChange:'change',
|
|
5858
5873
|
});
|
|
5874
|
+
function rowKeyTypeName(v){
|
|
5875
|
+
if(Array.isArray(v))return'array';
|
|
5876
|
+
if(v===null)return'null';
|
|
5877
|
+
return typeof v;
|
|
5878
|
+
}
|
|
5879
|
+
function assertRowKeyShape(rowKey){
|
|
5880
|
+
if(rowKey===undefined)return;
|
|
5881
|
+
if(typeof rowKey==='string'&&rowKey.length>0)return;
|
|
5882
|
+
if(typeof rowKey==='function')return;
|
|
5883
|
+
throw new Error(
|
|
5884
|
+
'lattice-kpi: rowKey must be a property name or a function; composite keys are not supported on tiles.',
|
|
5885
|
+
);
|
|
5886
|
+
}
|
|
5859
5887
|
function keyFn(rowKey){
|
|
5860
|
-
if(isFunction(rowKey))
|
|
5888
|
+
if(isFunction(rowKey)){
|
|
5889
|
+
return(row)=>{
|
|
5890
|
+
const key=rowKey(row);
|
|
5891
|
+
if(typeof key==='string')return key;
|
|
5892
|
+
if(typeof key==='number'&&Number.isFinite(key))return key;
|
|
5893
|
+
throw new Error(
|
|
5894
|
+
`lattice-kpi: rowKey function must return a string or number; got ${rowKeyTypeName(key)}.`,
|
|
5895
|
+
);
|
|
5896
|
+
};
|
|
5897
|
+
}
|
|
5861
5898
|
const get=pathGetter(typeof rowKey==='string'&&rowKey?rowKey:'id');
|
|
5862
5899
|
return(row)=>get(row);
|
|
5863
5900
|
}
|
|
@@ -5888,12 +5925,20 @@ format:spec.format,
|
|
|
5888
5925
|
target:spec.target,
|
|
5889
5926
|
barBounds:barBounds(spec),
|
|
5890
5927
|
baseline:spec.baseline,
|
|
5928
|
+
deltaMode:resolveDeltaMode(spec.delta,id),
|
|
5891
5929
|
spark:normaliseSpark(spec.sparkline),
|
|
5892
5930
|
acc,
|
|
5893
5931
|
members:0,
|
|
5894
5932
|
noColumn:false,
|
|
5895
5933
|
};
|
|
5896
5934
|
}
|
|
5935
|
+
function resolveDeltaMode(raw,id){
|
|
5936
|
+
if(raw===undefined)return'both';
|
|
5937
|
+
if(DELTA_MODES.includes(raw))return raw;
|
|
5938
|
+
warnOnce(`kpi:delta:${id}`,
|
|
5939
|
+
`kpi: tile "${id}" has delta: ${JSON.stringify(raw)}; expected one of ${DELTA_MODES.join(', ')}. Falling back to 'both'.`);
|
|
5940
|
+
return'both';
|
|
5941
|
+
}
|
|
5897
5942
|
function normaliseSpark(s){
|
|
5898
5943
|
if(!s)return null;
|
|
5899
5944
|
if(typeof s==='string')return{x:undefined,y:accessorFor(s)};
|
|
@@ -6038,6 +6083,7 @@ return rows;
|
|
|
6038
6083
|
}
|
|
6039
6084
|
function createKPI(el,config={}){
|
|
6040
6085
|
const cfg=isObject(config)?config:{};
|
|
6086
|
+
assertRowKeyShape(cfg.rowKey);
|
|
6041
6087
|
const gridBound=!!cfg.grid&&!Array.isArray(cfg.rows);
|
|
6042
6088
|
const key=gridBound?keyFn('__kpiKey'):keyFn(cfg.rowKey);
|
|
6043
6089
|
const nullText=typeof cfg.nullText==='string'?cfg.nullText:'—';
|
|
@@ -6139,6 +6185,7 @@ baseline:undefined,
|
|
|
6139
6185
|
delta:null,
|
|
6140
6186
|
deltaPercent:null,
|
|
6141
6187
|
deltaFormatted:undefined,
|
|
6188
|
+
deltaMode:undefined,
|
|
6142
6189
|
count:0,
|
|
6143
6190
|
sparkline:null,
|
|
6144
6191
|
bar:null,
|
|
@@ -6176,6 +6223,7 @@ baseline:t.baseline,
|
|
|
6176
6223
|
delta,
|
|
6177
6224
|
deltaPercent,
|
|
6178
6225
|
deltaFormatted,
|
|
6226
|
+
deltaMode:t.deltaMode,
|
|
6179
6227
|
count:t.members,
|
|
6180
6228
|
sparkline:sparkFor(t),
|
|
6181
6229
|
bar:t.barBounds
|