Comparing version 1.0.1 to 1.1.0
@@ -6,2 +6,3 @@ export interface ModifierConfig { | ||
} | ||
export type Comparator<T> = (original: T, selected: T) => boolean; | ||
export declare class ListSelectionStateManager<T> { | ||
@@ -12,2 +13,3 @@ /** | ||
private items; | ||
private comparator; | ||
private selected; | ||
@@ -20,2 +22,4 @@ private lastSelected; | ||
*/ | ||
private indexOfItem; | ||
private includesItem; | ||
private setRange; | ||
@@ -32,3 +36,3 @@ private setSingle; | ||
*/ | ||
constructor(items: T[]); | ||
constructor(items: T[], comparator?: Comparator<T>); | ||
/** | ||
@@ -35,0 +39,0 @@ * Public functions |
@@ -1,1 +0,1 @@ | ||
var lssm=function(n){"use strict";var p=Object.defineProperty;var I=(n,d,f)=>d in n?p(n,d,{enumerable:!0,configurable:!0,writable:!0,value:f}):n[d]=f;var a=(n,d,f)=>(I(n,typeof d!="symbol"?d+"":d,f),f);class d{constructor(t){a(this,"items",[]);a(this,"selected",[]);a(this,"lastSelected",null);a(this,"lastNonShiftToggled",null);a(this,"defaultConfig",{ctrlKey:!1,metaKey:!1,shiftKey:!1});this.items=t}setRange(t){if(this.selected.length){const s=this.lastNonShiftToggled,e=this.items.indexOf(s),i=this.items.indexOf(t);let h=0,l=0;if(this.isSelected(s))h=Math.min(e,i),l=Math.max(e,i);else{const r=this.asGroups(),c=r.find(o=>o.includes(this.items[i]));if(c)if(e>i){const o=r.indexOf(c)+1;h=i,l=this.items.findIndex(u=>u===r[o][0])}else h=this.items.findIndex(o=>o===c[0]),l=i;else{const o=r.findIndex(g=>g.some(x=>this.items.indexOf(x)>e)),u=this.items.findIndex(g=>g===r[o][0]);e>i?(h=i,l=u):(h=u,l=i)}}const S=this.items.slice(h,l+1),m=this.asGroups().filter(r=>!S.some(c=>r.includes(c)));this.set([...new Set([...S,...m.flat()])])}else{const s=this.items.indexOf(t);if(s<0)return;this.set(this.items.slice(0,s+1))}}setSingle(t){this.selected=[t]}toggle(t){this.isSelected(t)?this.remove(t):this.append(t)}remove(t){this.set(this.selected.filter(s=>s!==t))}append(t){this.isSelected(t)||this.set([...this.selected,t])}isSelected(t){return this.selected.includes(t)}asGroups(){return this.items.reduce((t,s)=>{if(!this.isSelected(s)||t.flat().includes(s))return t;let e=[s],i=this.items.indexOf(s);for(;this.isSelected(this.items[i+1]);)e=[...e,this.items[i+1]],i++;return[...t,e]},[])}getGroup(t){return this.isSelected?this.asGroups().find(s=>s.includes(t))??[]:[]}select(t,s=this.defaultConfig){s={...this.defaultConfig,...s};const{ctrlKey:e,shiftKey:i}=s,h=s.metaKey||e;return h?this.toggle(t):i&&!h?this.setRange(t):this.setSingle(t),this.isSelected(t)&&(this.lastSelected=t),i||(this.lastNonShiftToggled=t),this}next(t=this.defaultConfig){t={...this.defaultConfig,...t};const{shiftKey:s}=t;let e;if(!this.selected.length)return e=this.items[0],this.set([e]),this.lastSelected=e,this.lastNonShiftToggled=e,this;const i=this.items.indexOf(this.lastSelected),h=this.items.indexOf(this.lastNonShiftToggled);if(e=this.items[i+1],s){if(i>=h){this.append(e);const l=this.getGroup(e);this.lastSelected=l[l.length-1]}else{e=this.lastSelected;const l=this.getGroup(e);this.remove(e),this.lastSelected=l.length===1?l[0]:l[1],this.lastNonShiftToggled=l[l.length-1]}return this}else i===this.items.length-1?this.set([this.items[this.items.length-1]]):this.set([e]),this.lastSelected=e;return this}previous(t=this.defaultConfig){t={...this.defaultConfig,...t};const{shiftKey:s}=t;let e;if(!this.selected.length)return e=this.items[this.items.length-1],this.set([e]),this.lastSelected=e,this.lastNonShiftToggled=e,this;const i=this.items.indexOf(this.lastSelected),h=this.items.indexOf(this.lastNonShiftToggled);if(e=this.items[i-1],s){if(i<=h){this.append(e);const l=this.getGroup(e);this.lastSelected=l[0]}else{e=this.lastSelected;const l=this.getGroup(e);this.remove(e),this.lastNonShiftToggled=l[0],this.lastSelected=l[Math.max(0,l.length-2)]}return this}else i<1?this.set([this.items[0]]):this.set([e]),this.lastSelected=e;return this}get(){return this.selected.sort((t,s)=>this.items.indexOf(t)-this.items.indexOf(s))}getIndices(){return this.selected.map(t=>this.items.indexOf(t))}set(t){return this.selected=t.sort((s,e)=>this.items.indexOf(s)-this.items.indexOf(e)),this.selected.length||(this.lastSelected=null,this.lastNonShiftToggled=null),this}selectAll(){return this.set([...this.items]),this}clear(){return this.set([]),this}}return n.ListSelectionStateManager=d,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),n}({}); | ||
var lssm=function(n){"use strict";var p=Object.defineProperty;var x=(n,d,c)=>d in n?p(n,d,{enumerable:!0,configurable:!0,writable:!0,value:c}):n[d]=c;var a=(n,d,c)=>(x(n,typeof d!="symbol"?d+"":d,c),c);class d{constructor(t,s){a(this,"items",[]);a(this,"comparator");a(this,"selected",[]);a(this,"lastSelected",null);a(this,"lastNonShiftToggled",null);a(this,"defaultConfig",{ctrlKey:!1,metaKey:!1,shiftKey:!1});this.items=t,this.comparator=s}indexOfItem(t){return this.comparator?this.items.findIndex(s=>{var e;return(e=this.comparator)==null?void 0:e.call(this,s,t)}):this.items.indexOf(t)}includesItem(t,s){return this.comparator?t.some(e=>{var i;return(i=this.comparator)==null?void 0:i.call(this,e,s)}):t.includes(s)}setRange(t){if(this.selected.length){const s=this.lastNonShiftToggled,e=this.indexOfItem(s),i=this.indexOfItem(t);let l=0,h=0;if(this.isSelected(s))l=Math.min(e,i),h=Math.max(e,i);else{const r=this.asGroups(),f=r.find(o=>this.includesItem(o,this.items[i]));if(f)if(e>i){const o=r.indexOf(f)+1;l=i,h=this.items.findIndex(u=>u===r[o][0])}else l=this.items.findIndex(o=>o===f[0]),h=i;else{const o=r.findIndex(g=>g.some(I=>this.indexOfItem(I)>e)),u=this.items.findIndex(g=>g===r[o][0]);e>i?(l=i,h=u):(l=u,h=i)}}const m=this.items.slice(l,h+1),S=this.asGroups().filter(r=>!m.some(f=>this.includesItem(r,f)));this.set([...new Set([...m,...S.flat()])])}else{const s=this.indexOfItem(t);if(s<0)return;this.set(this.items.slice(0,s+1))}}setSingle(t){this.selected=[t]}toggle(t){this.isSelected(t)?this.remove(t):this.append(t)}remove(t){this.set(this.selected.filter(s=>s!==t))}append(t){this.isSelected(t)||this.set([...this.selected,t])}isSelected(t){return this.comparator!==void 0?this.selected.some(s=>{var e;return((e=this.comparator)==null?void 0:e.call(this,s,t))??!1}):this.includesItem(this.selected,t)}asGroups(){return this.items.reduce((t,s)=>{if(!this.isSelected(s)||this.includesItem(t.flat(),s))return t;let e=[s],i=this.indexOfItem(s);for(;this.isSelected(this.items[i+1]);)e=[...e,this.items[i+1]],i++;return[...t,e]},[])}getGroup(t){return this.isSelected?this.asGroups().find(s=>this.includesItem(s,t))??[]:[]}select(t,s=this.defaultConfig){s={...this.defaultConfig,...s};const{ctrlKey:e,shiftKey:i}=s,l=s.metaKey||e;return l?this.toggle(t):i&&!l?this.setRange(t):this.setSingle(t),this.isSelected(t)&&(this.lastSelected=t),i||(this.lastNonShiftToggled=t),this}next(t=this.defaultConfig){t={...this.defaultConfig,...t};const{shiftKey:s}=t;let e;if(!this.selected.length)return e=this.items[0],this.set([e]),this.lastSelected=e,this.lastNonShiftToggled=e,this;const i=this.indexOfItem(this.lastSelected),l=this.indexOfItem(this.lastNonShiftToggled);if(e=this.items[i+1],s){if(i>=l){this.append(e);const h=this.getGroup(e);this.lastSelected=h[h.length-1]}else{e=this.lastSelected;const h=this.getGroup(e);this.remove(e),this.lastSelected=h.length===1?h[0]:h[1],this.lastNonShiftToggled=h[h.length-1]}return this}else i===this.items.length-1?this.set([this.items[this.items.length-1]]):this.set([e]),this.lastSelected=e;return this}previous(t=this.defaultConfig){t={...this.defaultConfig,...t};const{shiftKey:s}=t;let e;if(!this.selected.length)return e=this.items[this.items.length-1],this.set([e]),this.lastSelected=e,this.lastNonShiftToggled=e,this;const i=this.indexOfItem(this.lastSelected),l=this.indexOfItem(this.lastNonShiftToggled);if(e=this.items[i-1],s){if(i<=l){this.append(e);const h=this.getGroup(e);this.lastSelected=h[0]}else{e=this.lastSelected;const h=this.getGroup(e);this.remove(e),this.lastNonShiftToggled=h[0],this.lastSelected=h[Math.max(0,h.length-2)]}return this}else i<1?this.set([this.items[0]]):this.set([e]),this.lastSelected=e;return this}get(){return this.selected.sort((t,s)=>this.indexOfItem(t)-this.indexOfItem(s))}getIndices(){return this.selected.map(t=>this.indexOfItem(t))}set(t){return this.selected=t.sort((s,e)=>this.indexOfItem(s)-this.indexOfItem(e)),this.selected.length||(this.lastSelected=null,this.lastNonShiftToggled=null),this}selectAll(){return this.set([...this.items]),this}clear(){return this.set([]),this}}return n.ListSelectionStateManager=d,Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),n}({}); |
{ | ||
"name": "lssm", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"repository": "https://github.com/syropian/lssm", | ||
@@ -5,0 +5,0 @@ "author": "Collin Henderson <collin@syropia.net>", |
@@ -33,7 +33,6 @@ # lssm [![Tests](https://github.com/syropian/lssm/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/syropian/lssm/actions/workflows/test.yml) | ||
const items = [ | ||
{ id: 1, name: 'Item 1' }, | ||
{ id: 2, name: 'Item 2' }, | ||
{ id: 3, name: 'Item 3' }, | ||
{ id: 4, name: 'Item 4' }, | ||
{ id: 5, name: 'Item 5' }, | ||
'Apple', | ||
'Banana', | ||
'Dragonfruit', | ||
'Strawberry', | ||
// etc... | ||
@@ -161,2 +160,23 @@ ] | ||
### Working with objects | ||
If you are using objects as your list items, you will need to pass a comparator function to the list manager. This is because `lssm` uses strict equality checks to compare items in the list, and objects are not strictly equal to each other even if they have the same properties. | ||
To solve this issue, you may pass a comparator function to the list manager. This function will be used to compare items in the list, and should return `true` if the items are equal, and `false` if they are not. | ||
**Example** | ||
```ts | ||
const items = [ | ||
{ id: 1, name: 'Item 1' }, | ||
{ id: 2, name: 'Item 2' }, | ||
{ id: 3, name: 'Item 3' }, | ||
{ id: 4, name: 'Item 4' }, | ||
{ id: 5, name: 'Item 5' }, | ||
] | ||
const itemComparator = (a, b) => a.id === b.id | ||
const listManager = new Lssm(items, itemComparator) | ||
``` | ||
## Development | ||
@@ -163,0 +183,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23116
261
198