@toclocoinc/lattice-grid 1.9.0 → 1.9.1

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.9.0 — htmx module
2
+ * Lattice Grid 1.9.1 — htmx module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -909,7 +909,14 @@ STDEV:(a)=>spread(numbers(a),true),
909
909
  STDEVP:(a)=>spread(numbers(a),false),
910
910
  VAR:(a)=>{const sd=spread(numbers(a),true);return sd*sd;},
911
911
  VARP:(a)=>{const sd=spread(numbers(a),false);return sd*sd;},
912
- COUNTDISTINCT:(a)=>new Set(a.filter((v)=>v!==null&&v!==undefined&&v!=='')).size,
912
+ COUNTDISTINCT:(a)=>{
913
+ const seen=new Set();
914
+ for(const arg of a){
915
+ const values=Array.isArray(arg)?arg:[arg];
916
+ for(const v of values)if(v!==null&&v!==undefined&&v!=='')seen.add(v);
917
+ }
918
+ return seen.size;
919
+ },
913
920
  IQR:(a)=>{
914
921
  const values=numbers(a);
915
922
  return percentileOf(values,0.75)-percentileOf(values,0.25);
@@ -6723,6 +6730,7 @@ const key=(ctx.row&&ctx.row.key)||api.keyOf(ctx.data);
6723
6730
  return key?api.running(source,spec.kind||'total',key):null;
6724
6731
  },
6725
6732
  };
6733
+ if(def.sort===undefined)m.sort={...(m.sort||{}),enabled:false};
6726
6734
  }
6727
6735
  const field=def.field??(isFunction(m.value&&m.value.compute)?null:(def.id??null));
6728
6736
  const computed=isFunction(m.value&&m.value.compute);
@@ -12943,14 +12951,22 @@ return this.#keyIndex.get(key);
12943
12951
  #changedColumns(previous,next){
12944
12952
  const changed=[];
12945
12953
  for(const colId of this.#queryColumns()){
12946
- const column=this.#column(colId);
12947
- if(!column)continue;
12948
- const before=isFunction(column.getValue)?column.getValue(previous):undefined;
12949
- const after=isFunction(column.getValue)?column.getValue(next):undefined;
12950
- if(!Object.is(before,after))changed.push(colId);
12954
+ if(this.#column(colId)&&this.#moved(colId,previous,next,new Set()))changed.push(colId);
12951
12955
  }
12952
12956
  return changed;
12953
12957
  }
12958
+ #moved(colId,previous,next,seen){
12959
+ if(seen.has(colId))return false;
12960
+ seen.add(colId);
12961
+ const column=this.#column(colId);
12962
+ if(!column)return false;
12963
+ const deps=column.value&&column.value.deps;
12964
+ if(Array.isArray(deps)&&deps.length){
12965
+ return deps.some((dep)=>this.#moved(String(dep),previous,next,seen));
12966
+ }
12967
+ if(!isFunction(column.getValue))return false;
12968
+ return!Object.is(column.getValue(previous),column.getValue(next));
12969
+ }
12954
12970
  #queryColumns(){
12955
12971
  const ids=new Set();
12956
12972
  for(const entry of this.#state('sort',[]))ids.add(entry.col);
@@ -13099,7 +13115,16 @@ handleFor(colId){
13099
13115
  return this.#handles.handle(colId);
13100
13116
  }
13101
13117
  #runSort(filtered){
13102
- const entries=this.#state('sort',[]);
13118
+ const entries=this.#state('sort',[]).filter((entry)=>{
13119
+ const column=this.#column(entry.col);
13120
+ if(!column||!column.running)return true;
13121
+ warnOnce(
13122
+ `source.sort.running.${entry.col}`,
13123
+ `sort ignores "${entry.col}": a running total is a function of the sort order, `
13124
+ +'so it cannot also decide it. Sort by the column it runs over instead.',
13125
+ );
13126
+ return false;
13127
+ });
13103
13128
  if(!entries.length)return filtered;
13104
13129
  const locale=(this.#ctx.config||{}).locale;
13105
13130
  if(entries.length===1){
@@ -28625,6 +28650,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
28625
28650
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return parseRadix;}});
28626
28651
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return formatRadix;}});
28627
28652
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return createUnitType;}});
28653
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return registerUnitSystem;}});
28654
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return defineUnit;}});
28628
28655
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return UNIT_SYSTEMS;}});
28629
28656
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return parseUnit;}});
28630
28657
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return formatUnit;}});
@@ -28635,6 +28662,8 @@ const RADIX_PRESETS=__m0["RADIX_PRESETS"];
28635
28662
  const parseRadix=__m0["parseRadix"];
28636
28663
  const formatRadix=__m0["formatRadix"];
28637
28664
  const createUnitType=__m0["createUnitType"];
28665
+ const registerUnitSystem=__m0["registerUnitSystem"];
28666
+ const defineUnit=__m0["defineUnit"];
28638
28667
  const UNIT_SYSTEMS=__m0["UNIT_SYSTEMS"];
28639
28668
  const parseUnit=__m0["parseUnit"];
28640
28669
  const formatUnit=__m0["formatUnit"];
@@ -38086,6 +38115,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
38086
38115
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return __m5["parseRadix"];}});
38087
38116
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return __m5["formatRadix"];}});
38088
38117
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return __m5["createUnitType"];}});
38118
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return __m5["registerUnitSystem"];}});
38119
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return __m5["defineUnit"];}});
38089
38120
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return __m5["UNIT_SYSTEMS"];}});
38090
38121
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return __m5["parseUnit"];}});
38091
38122
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return __m5["formatUnit"];}});
@@ -59659,6 +59690,12 @@ const __m3=__req("packages/dom/src/renderer/textentry.js");
59659
59690
  const isTextEntry=__m3["isTextEntry"];
59660
59691
  const IN_RANGE='lat-cell--range';
59661
59692
  const RANGE_EDGE='lat-cell--range-edge';
59693
+ const EDGE_SIDES=Object.freeze({
59694
+ top:'lat-cell--range-top',
59695
+ right:'lat-cell--range-right',
59696
+ bottom:'lat-cell--range-bottom',
59697
+ left:'lat-cell--range-left',
59698
+ });
59662
59699
  const DRAG_THRESHOLD=3;
59663
59700
  class RangeController{
59664
59701
  #grid;
@@ -59920,7 +59957,13 @@ if(!Number.isFinite(index)||index<0)continue;
59920
59957
  const inRange=hasRange&&selection.inRange(index,colId);
59921
59958
  const inPreview=!!preview&&this.#inFillPreview(index,colId,preview);
59922
59959
  cell.classList.toggle(IN_RANGE,inRange||inPreview);
59923
- cell.classList.toggle(RANGE_EDGE,(inRange||inPreview)&&this.#isEdge(index,colId,selection));
59960
+ const edges=(inRange||inPreview)
59961
+ ?this.#edgesOf(index,colId,selection)
59962
+ :null;
59963
+ cell.classList.toggle(RANGE_EDGE,!!edges&&edges.any);
59964
+ for(const[side,className]of Object.entries(EDGE_SIDES)){
59965
+ cell.classList.toggle(className,!!edges&&edges[side]);
59966
+ }
59924
59967
  }
59925
59968
  this.#placeHandle();
59926
59969
  }
@@ -59932,15 +59975,19 @@ if(!columns.has(colId))return false;
59932
59975
  const last=this.#indexOfKey([...new Set(cells.map((c)=>c.key))].pop());
59933
59976
  return index>last&&index<=preview.rowIndex;
59934
59977
  }
59935
- #isEdge(index,colId,selection){
59978
+ #edgesOf(index,colId,selection){
59936
59979
  const columns=this.#grid.columns.visible().map((c)=>c.id);
59937
59980
  const at=columns.indexOf(colId);
59938
- const left=at>0?columns[at-1]:null;
59939
- const right=at<columns.length-1?columns[at+1]:null;
59940
- return!selection.inRange(index-1,colId)
59941
- ||!selection.inRange(index+1,colId)
59942
- ||!left||!selection.inRange(index,left)
59943
- ||!right||!selection.inRange(index,right);
59981
+ const before=at>0?columns[at-1]:null;
59982
+ const after=at>=0&&at<columns.length-1?columns[at+1]:null;
59983
+ const edges={
59984
+ top:!selection.inRange(index-1,colId),
59985
+ bottom:!selection.inRange(index+1,colId),
59986
+ left:!before||!selection.inRange(index,before),
59987
+ right:!after||!selection.inRange(index,after),
59988
+ };
59989
+ edges.any=edges.top||edges.bottom||edges.left||edges.right;
59990
+ return edges;
59944
59991
  }
59945
59992
  #placeHandle(){
59946
59993
  const corner=this.#grid.selection.corner();
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.9.0 — htmx module
2
+ * Lattice Grid 1.9.1 — htmx module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -911,7 +911,14 @@ STDEV:(a)=>spread(numbers(a),true),
911
911
  STDEVP:(a)=>spread(numbers(a),false),
912
912
  VAR:(a)=>{const sd=spread(numbers(a),true);return sd*sd;},
913
913
  VARP:(a)=>{const sd=spread(numbers(a),false);return sd*sd;},
914
- COUNTDISTINCT:(a)=>new Set(a.filter((v)=>v!==null&&v!==undefined&&v!=='')).size,
914
+ COUNTDISTINCT:(a)=>{
915
+ const seen=new Set();
916
+ for(const arg of a){
917
+ const values=Array.isArray(arg)?arg:[arg];
918
+ for(const v of values)if(v!==null&&v!==undefined&&v!=='')seen.add(v);
919
+ }
920
+ return seen.size;
921
+ },
915
922
  IQR:(a)=>{
916
923
  const values=numbers(a);
917
924
  return percentileOf(values,0.75)-percentileOf(values,0.25);
@@ -6725,6 +6732,7 @@ const key=(ctx.row&&ctx.row.key)||api.keyOf(ctx.data);
6725
6732
  return key?api.running(source,spec.kind||'total',key):null;
6726
6733
  },
6727
6734
  };
6735
+ if(def.sort===undefined)m.sort={...(m.sort||{}),enabled:false};
6728
6736
  }
6729
6737
  const field=def.field??(isFunction(m.value&&m.value.compute)?null:(def.id??null));
6730
6738
  const computed=isFunction(m.value&&m.value.compute);
@@ -12945,14 +12953,22 @@ return this.#keyIndex.get(key);
12945
12953
  #changedColumns(previous,next){
12946
12954
  const changed=[];
12947
12955
  for(const colId of this.#queryColumns()){
12948
- const column=this.#column(colId);
12949
- if(!column)continue;
12950
- const before=isFunction(column.getValue)?column.getValue(previous):undefined;
12951
- const after=isFunction(column.getValue)?column.getValue(next):undefined;
12952
- if(!Object.is(before,after))changed.push(colId);
12956
+ if(this.#column(colId)&&this.#moved(colId,previous,next,new Set()))changed.push(colId);
12953
12957
  }
12954
12958
  return changed;
12955
12959
  }
12960
+ #moved(colId,previous,next,seen){
12961
+ if(seen.has(colId))return false;
12962
+ seen.add(colId);
12963
+ const column=this.#column(colId);
12964
+ if(!column)return false;
12965
+ const deps=column.value&&column.value.deps;
12966
+ if(Array.isArray(deps)&&deps.length){
12967
+ return deps.some((dep)=>this.#moved(String(dep),previous,next,seen));
12968
+ }
12969
+ if(!isFunction(column.getValue))return false;
12970
+ return!Object.is(column.getValue(previous),column.getValue(next));
12971
+ }
12956
12972
  #queryColumns(){
12957
12973
  const ids=new Set();
12958
12974
  for(const entry of this.#state('sort',[]))ids.add(entry.col);
@@ -13101,7 +13117,16 @@ handleFor(colId){
13101
13117
  return this.#handles.handle(colId);
13102
13118
  }
13103
13119
  #runSort(filtered){
13104
- const entries=this.#state('sort',[]);
13120
+ const entries=this.#state('sort',[]).filter((entry)=>{
13121
+ const column=this.#column(entry.col);
13122
+ if(!column||!column.running)return true;
13123
+ warnOnce(
13124
+ `source.sort.running.${entry.col}`,
13125
+ `sort ignores "${entry.col}": a running total is a function of the sort order, `
13126
+ +'so it cannot also decide it. Sort by the column it runs over instead.',
13127
+ );
13128
+ return false;
13129
+ });
13105
13130
  if(!entries.length)return filtered;
13106
13131
  const locale=(this.#ctx.config||{}).locale;
13107
13132
  if(entries.length===1){
@@ -28627,6 +28652,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
28627
28652
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return parseRadix;}});
28628
28653
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return formatRadix;}});
28629
28654
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return createUnitType;}});
28655
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return registerUnitSystem;}});
28656
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return defineUnit;}});
28630
28657
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return UNIT_SYSTEMS;}});
28631
28658
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return parseUnit;}});
28632
28659
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return formatUnit;}});
@@ -28637,6 +28664,8 @@ const RADIX_PRESETS=__m0["RADIX_PRESETS"];
28637
28664
  const parseRadix=__m0["parseRadix"];
28638
28665
  const formatRadix=__m0["formatRadix"];
28639
28666
  const createUnitType=__m0["createUnitType"];
28667
+ const registerUnitSystem=__m0["registerUnitSystem"];
28668
+ const defineUnit=__m0["defineUnit"];
28640
28669
  const UNIT_SYSTEMS=__m0["UNIT_SYSTEMS"];
28641
28670
  const parseUnit=__m0["parseUnit"];
28642
28671
  const formatUnit=__m0["formatUnit"];
@@ -38088,6 +38117,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
38088
38117
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return __m5["parseRadix"];}});
38089
38118
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return __m5["formatRadix"];}});
38090
38119
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return __m5["createUnitType"];}});
38120
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return __m5["registerUnitSystem"];}});
38121
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return __m5["defineUnit"];}});
38091
38122
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return __m5["UNIT_SYSTEMS"];}});
38092
38123
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return __m5["parseUnit"];}});
38093
38124
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return __m5["formatUnit"];}});
@@ -59661,6 +59692,12 @@ const __m3=__req("packages/dom/src/renderer/textentry.js");
59661
59692
  const isTextEntry=__m3["isTextEntry"];
59662
59693
  const IN_RANGE='lat-cell--range';
59663
59694
  const RANGE_EDGE='lat-cell--range-edge';
59695
+ const EDGE_SIDES=Object.freeze({
59696
+ top:'lat-cell--range-top',
59697
+ right:'lat-cell--range-right',
59698
+ bottom:'lat-cell--range-bottom',
59699
+ left:'lat-cell--range-left',
59700
+ });
59664
59701
  const DRAG_THRESHOLD=3;
59665
59702
  class RangeController{
59666
59703
  #grid;
@@ -59922,7 +59959,13 @@ if(!Number.isFinite(index)||index<0)continue;
59922
59959
  const inRange=hasRange&&selection.inRange(index,colId);
59923
59960
  const inPreview=!!preview&&this.#inFillPreview(index,colId,preview);
59924
59961
  cell.classList.toggle(IN_RANGE,inRange||inPreview);
59925
- cell.classList.toggle(RANGE_EDGE,(inRange||inPreview)&&this.#isEdge(index,colId,selection));
59962
+ const edges=(inRange||inPreview)
59963
+ ?this.#edgesOf(index,colId,selection)
59964
+ :null;
59965
+ cell.classList.toggle(RANGE_EDGE,!!edges&&edges.any);
59966
+ for(const[side,className]of Object.entries(EDGE_SIDES)){
59967
+ cell.classList.toggle(className,!!edges&&edges[side]);
59968
+ }
59926
59969
  }
59927
59970
  this.#placeHandle();
59928
59971
  }
@@ -59934,15 +59977,19 @@ if(!columns.has(colId))return false;
59934
59977
  const last=this.#indexOfKey([...new Set(cells.map((c)=>c.key))].pop());
59935
59978
  return index>last&&index<=preview.rowIndex;
59936
59979
  }
59937
- #isEdge(index,colId,selection){
59980
+ #edgesOf(index,colId,selection){
59938
59981
  const columns=this.#grid.columns.visible().map((c)=>c.id);
59939
59982
  const at=columns.indexOf(colId);
59940
- const left=at>0?columns[at-1]:null;
59941
- const right=at<columns.length-1?columns[at+1]:null;
59942
- return!selection.inRange(index-1,colId)
59943
- ||!selection.inRange(index+1,colId)
59944
- ||!left||!selection.inRange(index,left)
59945
- ||!right||!selection.inRange(index,right);
59983
+ const before=at>0?columns[at-1]:null;
59984
+ const after=at>=0&&at<columns.length-1?columns[at+1]:null;
59985
+ const edges={
59986
+ top:!selection.inRange(index-1,colId),
59987
+ bottom:!selection.inRange(index+1,colId),
59988
+ left:!before||!selection.inRange(index,before),
59989
+ right:!after||!selection.inRange(index,after),
59990
+ };
59991
+ edges.any=edges.top||edges.bottom||edges.left||edges.right;
59992
+ return edges;
59946
59993
  }
59947
59994
  #placeHandle(){
59948
59995
  const corner=this.#grid.selection.corner();
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.9.0 — htmx module
2
+ * Lattice Grid 1.9.1 — htmx module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -911,7 +911,14 @@ STDEV:(a)=>spread(numbers(a),true),
911
911
  STDEVP:(a)=>spread(numbers(a),false),
912
912
  VAR:(a)=>{const sd=spread(numbers(a),true);return sd*sd;},
913
913
  VARP:(a)=>{const sd=spread(numbers(a),false);return sd*sd;},
914
- COUNTDISTINCT:(a)=>new Set(a.filter((v)=>v!==null&&v!==undefined&&v!=='')).size,
914
+ COUNTDISTINCT:(a)=>{
915
+ const seen=new Set();
916
+ for(const arg of a){
917
+ const values=Array.isArray(arg)?arg:[arg];
918
+ for(const v of values)if(v!==null&&v!==undefined&&v!=='')seen.add(v);
919
+ }
920
+ return seen.size;
921
+ },
915
922
  IQR:(a)=>{
916
923
  const values=numbers(a);
917
924
  return percentileOf(values,0.75)-percentileOf(values,0.25);
@@ -6725,6 +6732,7 @@ const key=(ctx.row&&ctx.row.key)||api.keyOf(ctx.data);
6725
6732
  return key?api.running(source,spec.kind||'total',key):null;
6726
6733
  },
6727
6734
  };
6735
+ if(def.sort===undefined)m.sort={...(m.sort||{}),enabled:false};
6728
6736
  }
6729
6737
  const field=def.field??(isFunction(m.value&&m.value.compute)?null:(def.id??null));
6730
6738
  const computed=isFunction(m.value&&m.value.compute);
@@ -12945,14 +12953,22 @@ return this.#keyIndex.get(key);
12945
12953
  #changedColumns(previous,next){
12946
12954
  const changed=[];
12947
12955
  for(const colId of this.#queryColumns()){
12948
- const column=this.#column(colId);
12949
- if(!column)continue;
12950
- const before=isFunction(column.getValue)?column.getValue(previous):undefined;
12951
- const after=isFunction(column.getValue)?column.getValue(next):undefined;
12952
- if(!Object.is(before,after))changed.push(colId);
12956
+ if(this.#column(colId)&&this.#moved(colId,previous,next,new Set()))changed.push(colId);
12953
12957
  }
12954
12958
  return changed;
12955
12959
  }
12960
+ #moved(colId,previous,next,seen){
12961
+ if(seen.has(colId))return false;
12962
+ seen.add(colId);
12963
+ const column=this.#column(colId);
12964
+ if(!column)return false;
12965
+ const deps=column.value&&column.value.deps;
12966
+ if(Array.isArray(deps)&&deps.length){
12967
+ return deps.some((dep)=>this.#moved(String(dep),previous,next,seen));
12968
+ }
12969
+ if(!isFunction(column.getValue))return false;
12970
+ return!Object.is(column.getValue(previous),column.getValue(next));
12971
+ }
12956
12972
  #queryColumns(){
12957
12973
  const ids=new Set();
12958
12974
  for(const entry of this.#state('sort',[]))ids.add(entry.col);
@@ -13101,7 +13117,16 @@ handleFor(colId){
13101
13117
  return this.#handles.handle(colId);
13102
13118
  }
13103
13119
  #runSort(filtered){
13104
- const entries=this.#state('sort',[]);
13120
+ const entries=this.#state('sort',[]).filter((entry)=>{
13121
+ const column=this.#column(entry.col);
13122
+ if(!column||!column.running)return true;
13123
+ warnOnce(
13124
+ `source.sort.running.${entry.col}`,
13125
+ `sort ignores "${entry.col}": a running total is a function of the sort order, `
13126
+ +'so it cannot also decide it. Sort by the column it runs over instead.',
13127
+ );
13128
+ return false;
13129
+ });
13105
13130
  if(!entries.length)return filtered;
13106
13131
  const locale=(this.#ctx.config||{}).locale;
13107
13132
  if(entries.length===1){
@@ -28627,6 +28652,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
28627
28652
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return parseRadix;}});
28628
28653
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return formatRadix;}});
28629
28654
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return createUnitType;}});
28655
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return registerUnitSystem;}});
28656
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return defineUnit;}});
28630
28657
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return UNIT_SYSTEMS;}});
28631
28658
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return parseUnit;}});
28632
28659
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return formatUnit;}});
@@ -28637,6 +28664,8 @@ const RADIX_PRESETS=__m0["RADIX_PRESETS"];
28637
28664
  const parseRadix=__m0["parseRadix"];
28638
28665
  const formatRadix=__m0["formatRadix"];
28639
28666
  const createUnitType=__m0["createUnitType"];
28667
+ const registerUnitSystem=__m0["registerUnitSystem"];
28668
+ const defineUnit=__m0["defineUnit"];
28640
28669
  const UNIT_SYSTEMS=__m0["UNIT_SYSTEMS"];
28641
28670
  const parseUnit=__m0["parseUnit"];
28642
28671
  const formatUnit=__m0["formatUnit"];
@@ -38088,6 +38117,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
38088
38117
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return __m5["parseRadix"];}});
38089
38118
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return __m5["formatRadix"];}});
38090
38119
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return __m5["createUnitType"];}});
38120
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return __m5["registerUnitSystem"];}});
38121
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return __m5["defineUnit"];}});
38091
38122
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return __m5["UNIT_SYSTEMS"];}});
38092
38123
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return __m5["parseUnit"];}});
38093
38124
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return __m5["formatUnit"];}});
@@ -59661,6 +59692,12 @@ const __m3=__req("packages/dom/src/renderer/textentry.js");
59661
59692
  const isTextEntry=__m3["isTextEntry"];
59662
59693
  const IN_RANGE='lat-cell--range';
59663
59694
  const RANGE_EDGE='lat-cell--range-edge';
59695
+ const EDGE_SIDES=Object.freeze({
59696
+ top:'lat-cell--range-top',
59697
+ right:'lat-cell--range-right',
59698
+ bottom:'lat-cell--range-bottom',
59699
+ left:'lat-cell--range-left',
59700
+ });
59664
59701
  const DRAG_THRESHOLD=3;
59665
59702
  class RangeController{
59666
59703
  #grid;
@@ -59922,7 +59959,13 @@ if(!Number.isFinite(index)||index<0)continue;
59922
59959
  const inRange=hasRange&&selection.inRange(index,colId);
59923
59960
  const inPreview=!!preview&&this.#inFillPreview(index,colId,preview);
59924
59961
  cell.classList.toggle(IN_RANGE,inRange||inPreview);
59925
- cell.classList.toggle(RANGE_EDGE,(inRange||inPreview)&&this.#isEdge(index,colId,selection));
59962
+ const edges=(inRange||inPreview)
59963
+ ?this.#edgesOf(index,colId,selection)
59964
+ :null;
59965
+ cell.classList.toggle(RANGE_EDGE,!!edges&&edges.any);
59966
+ for(const[side,className]of Object.entries(EDGE_SIDES)){
59967
+ cell.classList.toggle(className,!!edges&&edges[side]);
59968
+ }
59926
59969
  }
59927
59970
  this.#placeHandle();
59928
59971
  }
@@ -59934,15 +59977,19 @@ if(!columns.has(colId))return false;
59934
59977
  const last=this.#indexOfKey([...new Set(cells.map((c)=>c.key))].pop());
59935
59978
  return index>last&&index<=preview.rowIndex;
59936
59979
  }
59937
- #isEdge(index,colId,selection){
59980
+ #edgesOf(index,colId,selection){
59938
59981
  const columns=this.#grid.columns.visible().map((c)=>c.id);
59939
59982
  const at=columns.indexOf(colId);
59940
- const left=at>0?columns[at-1]:null;
59941
- const right=at<columns.length-1?columns[at+1]:null;
59942
- return!selection.inRange(index-1,colId)
59943
- ||!selection.inRange(index+1,colId)
59944
- ||!left||!selection.inRange(index,left)
59945
- ||!right||!selection.inRange(index,right);
59983
+ const before=at>0?columns[at-1]:null;
59984
+ const after=at>=0&&at<columns.length-1?columns[at+1]:null;
59985
+ const edges={
59986
+ top:!selection.inRange(index-1,colId),
59987
+ bottom:!selection.inRange(index+1,colId),
59988
+ left:!before||!selection.inRange(index,before),
59989
+ right:!after||!selection.inRange(index,after),
59990
+ };
59991
+ edges.any=edges.top||edges.bottom||edges.left||edges.right;
59992
+ return edges;
59946
59993
  }
59947
59994
  #placeHandle(){
59948
59995
  const corner=this.#grid.selection.corner();
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.9.0 — react module
2
+ * Lattice Grid 1.9.1 — react module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.9.0 — svelte module
2
+ * Lattice Grid 1.9.1 — svelte module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.9.0 — vue module
2
+ * Lattice Grid 1.9.1 — vue module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.9.0 — webcomponent module
2
+ * Lattice Grid 1.9.1 — webcomponent module
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -909,7 +909,14 @@ STDEV:(a)=>spread(numbers(a),true),
909
909
  STDEVP:(a)=>spread(numbers(a),false),
910
910
  VAR:(a)=>{const sd=spread(numbers(a),true);return sd*sd;},
911
911
  VARP:(a)=>{const sd=spread(numbers(a),false);return sd*sd;},
912
- COUNTDISTINCT:(a)=>new Set(a.filter((v)=>v!==null&&v!==undefined&&v!=='')).size,
912
+ COUNTDISTINCT:(a)=>{
913
+ const seen=new Set();
914
+ for(const arg of a){
915
+ const values=Array.isArray(arg)?arg:[arg];
916
+ for(const v of values)if(v!==null&&v!==undefined&&v!=='')seen.add(v);
917
+ }
918
+ return seen.size;
919
+ },
913
920
  IQR:(a)=>{
914
921
  const values=numbers(a);
915
922
  return percentileOf(values,0.75)-percentileOf(values,0.25);
@@ -6723,6 +6730,7 @@ const key=(ctx.row&&ctx.row.key)||api.keyOf(ctx.data);
6723
6730
  return key?api.running(source,spec.kind||'total',key):null;
6724
6731
  },
6725
6732
  };
6733
+ if(def.sort===undefined)m.sort={...(m.sort||{}),enabled:false};
6726
6734
  }
6727
6735
  const field=def.field??(isFunction(m.value&&m.value.compute)?null:(def.id??null));
6728
6736
  const computed=isFunction(m.value&&m.value.compute);
@@ -12943,14 +12951,22 @@ return this.#keyIndex.get(key);
12943
12951
  #changedColumns(previous,next){
12944
12952
  const changed=[];
12945
12953
  for(const colId of this.#queryColumns()){
12946
- const column=this.#column(colId);
12947
- if(!column)continue;
12948
- const before=isFunction(column.getValue)?column.getValue(previous):undefined;
12949
- const after=isFunction(column.getValue)?column.getValue(next):undefined;
12950
- if(!Object.is(before,after))changed.push(colId);
12954
+ if(this.#column(colId)&&this.#moved(colId,previous,next,new Set()))changed.push(colId);
12951
12955
  }
12952
12956
  return changed;
12953
12957
  }
12958
+ #moved(colId,previous,next,seen){
12959
+ if(seen.has(colId))return false;
12960
+ seen.add(colId);
12961
+ const column=this.#column(colId);
12962
+ if(!column)return false;
12963
+ const deps=column.value&&column.value.deps;
12964
+ if(Array.isArray(deps)&&deps.length){
12965
+ return deps.some((dep)=>this.#moved(String(dep),previous,next,seen));
12966
+ }
12967
+ if(!isFunction(column.getValue))return false;
12968
+ return!Object.is(column.getValue(previous),column.getValue(next));
12969
+ }
12954
12970
  #queryColumns(){
12955
12971
  const ids=new Set();
12956
12972
  for(const entry of this.#state('sort',[]))ids.add(entry.col);
@@ -13099,7 +13115,16 @@ handleFor(colId){
13099
13115
  return this.#handles.handle(colId);
13100
13116
  }
13101
13117
  #runSort(filtered){
13102
- const entries=this.#state('sort',[]);
13118
+ const entries=this.#state('sort',[]).filter((entry)=>{
13119
+ const column=this.#column(entry.col);
13120
+ if(!column||!column.running)return true;
13121
+ warnOnce(
13122
+ `source.sort.running.${entry.col}`,
13123
+ `sort ignores "${entry.col}": a running total is a function of the sort order, `
13124
+ +'so it cannot also decide it. Sort by the column it runs over instead.',
13125
+ );
13126
+ return false;
13127
+ });
13103
13128
  if(!entries.length)return filtered;
13104
13129
  const locale=(this.#ctx.config||{}).locale;
13105
13130
  if(entries.length===1){
@@ -28625,6 +28650,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
28625
28650
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return parseRadix;}});
28626
28651
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return formatRadix;}});
28627
28652
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return createUnitType;}});
28653
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return registerUnitSystem;}});
28654
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return defineUnit;}});
28628
28655
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return UNIT_SYSTEMS;}});
28629
28656
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return parseUnit;}});
28630
28657
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return formatUnit;}});
@@ -28635,6 +28662,8 @@ const RADIX_PRESETS=__m0["RADIX_PRESETS"];
28635
28662
  const parseRadix=__m0["parseRadix"];
28636
28663
  const formatRadix=__m0["formatRadix"];
28637
28664
  const createUnitType=__m0["createUnitType"];
28665
+ const registerUnitSystem=__m0["registerUnitSystem"];
28666
+ const defineUnit=__m0["defineUnit"];
28638
28667
  const UNIT_SYSTEMS=__m0["UNIT_SYSTEMS"];
28639
28668
  const parseUnit=__m0["parseUnit"];
28640
28669
  const formatUnit=__m0["formatUnit"];
@@ -38086,6 +38115,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
38086
38115
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return __m5["parseRadix"];}});
38087
38116
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return __m5["formatRadix"];}});
38088
38117
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return __m5["createUnitType"];}});
38118
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return __m5["registerUnitSystem"];}});
38119
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return __m5["defineUnit"];}});
38089
38120
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return __m5["UNIT_SYSTEMS"];}});
38090
38121
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return __m5["parseUnit"];}});
38091
38122
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return __m5["formatUnit"];}});
@@ -59659,6 +59690,12 @@ const __m3=__req("packages/dom/src/renderer/textentry.js");
59659
59690
  const isTextEntry=__m3["isTextEntry"];
59660
59691
  const IN_RANGE='lat-cell--range';
59661
59692
  const RANGE_EDGE='lat-cell--range-edge';
59693
+ const EDGE_SIDES=Object.freeze({
59694
+ top:'lat-cell--range-top',
59695
+ right:'lat-cell--range-right',
59696
+ bottom:'lat-cell--range-bottom',
59697
+ left:'lat-cell--range-left',
59698
+ });
59662
59699
  const DRAG_THRESHOLD=3;
59663
59700
  class RangeController{
59664
59701
  #grid;
@@ -59920,7 +59957,13 @@ if(!Number.isFinite(index)||index<0)continue;
59920
59957
  const inRange=hasRange&&selection.inRange(index,colId);
59921
59958
  const inPreview=!!preview&&this.#inFillPreview(index,colId,preview);
59922
59959
  cell.classList.toggle(IN_RANGE,inRange||inPreview);
59923
- cell.classList.toggle(RANGE_EDGE,(inRange||inPreview)&&this.#isEdge(index,colId,selection));
59960
+ const edges=(inRange||inPreview)
59961
+ ?this.#edgesOf(index,colId,selection)
59962
+ :null;
59963
+ cell.classList.toggle(RANGE_EDGE,!!edges&&edges.any);
59964
+ for(const[side,className]of Object.entries(EDGE_SIDES)){
59965
+ cell.classList.toggle(className,!!edges&&edges[side]);
59966
+ }
59924
59967
  }
59925
59968
  this.#placeHandle();
59926
59969
  }
@@ -59932,15 +59975,19 @@ if(!columns.has(colId))return false;
59932
59975
  const last=this.#indexOfKey([...new Set(cells.map((c)=>c.key))].pop());
59933
59976
  return index>last&&index<=preview.rowIndex;
59934
59977
  }
59935
- #isEdge(index,colId,selection){
59978
+ #edgesOf(index,colId,selection){
59936
59979
  const columns=this.#grid.columns.visible().map((c)=>c.id);
59937
59980
  const at=columns.indexOf(colId);
59938
- const left=at>0?columns[at-1]:null;
59939
- const right=at<columns.length-1?columns[at+1]:null;
59940
- return!selection.inRange(index-1,colId)
59941
- ||!selection.inRange(index+1,colId)
59942
- ||!left||!selection.inRange(index,left)
59943
- ||!right||!selection.inRange(index,right);
59981
+ const before=at>0?columns[at-1]:null;
59982
+ const after=at>=0&&at<columns.length-1?columns[at+1]:null;
59983
+ const edges={
59984
+ top:!selection.inRange(index-1,colId),
59985
+ bottom:!selection.inRange(index+1,colId),
59986
+ left:!before||!selection.inRange(index,before),
59987
+ right:!after||!selection.inRange(index,after),
59988
+ };
59989
+ edges.any=edges.top||edges.bottom||edges.left||edges.right;
59990
+ return edges;
59944
59991
  }
59945
59992
  #placeHandle(){
59946
59993
  const corner=this.#grid.selection.corner();
@@ -63043,6 +63090,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
63043
63090
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return __m4["parseRadix"];}});
63044
63091
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return __m4["formatRadix"];}});
63045
63092
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return __m4["createUnitType"];}});
63093
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return __m4["registerUnitSystem"];}});
63094
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return __m4["defineUnit"];}});
63046
63095
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return __m4["UNIT_SYSTEMS"];}});
63047
63096
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return __m4["parseUnit"];}});
63048
63097
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return __m4["formatUnit"];}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toclocoinc/lattice-grid",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
4
4
  "description": "Lattice Grid — high performance JavaScript data grid. TOCLOCO Inc.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "TOCLOCO Inc",