masonry-simple 3.2.1 → 4.0.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.
@@ -1,3 +1,4 @@
1
1
  node_modules
2
- .parcel
3
2
  dist
3
+ .parcel
4
+ .parcel-cache
@@ -0,0 +1,11 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "printWidth": 100,
5
+ "trailingComma": "all",
6
+ "arrowParens": "always",
7
+ "tabWidth": 2,
8
+ "useTabs": false,
9
+ "bracketSpacing": true,
10
+ "endOfLine": "lf"
11
+ }
@@ -1 +1 @@
1
- {"mappings":"AAAA,qBAAM,aAAa;gBAaL,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;KAAO;IA+BvD,IAAI;IAgBJ,OAAO;CAcf;AAED,eAAe,aAAa,CAAC","sources":["src/src/index.ts","src/index.ts"],"sourcesContent":[null,"class MasonrySimple {\n private readonly container: HTMLElement | null = null;\n\n private gridItems: HTMLElement[] = [];\n\n private rowHeight: number = 1;\n\n private rowGap: number = 0;\n\n private resizeTimeout: number | null = null;\n\n private resizeObserver: ResizeObserver;\n\n constructor(options: { container?: HTMLElement | string } = {}) {\n this.container = options.container instanceof HTMLElement\n ? options.container\n : document.querySelector(options.container || '.masonry') as HTMLElement;\n\n this.resizeObserver = new ResizeObserver(() => this.handleResize());\n }\n\n private handleResize() {\n if (this.resizeTimeout !== null) {\n window.cancelAnimationFrame(this.resizeTimeout);\n }\n\n this.resizeTimeout = window.requestAnimationFrame(() => this.resizeAllItems());\n }\n\n private resizeAllItems() {\n if (!this.container) return;\n\n this.container.style.alignItems = 'start';\n this.gridItems.forEach((item) => {\n const rowSpan = Math.ceil(\n (item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap),\n );\n\n const { style } = item;\n\n style.gridRowEnd = `span ${rowSpan}`;\n });\n }\n\n public init() {\n if (!this.container) return;\n\n const computedStyle = getComputedStyle(this.container);\n\n this.rowGap = parseInt(computedStyle.rowGap, 10);\n this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;\n\n this.gridItems = Array.from(this.container.children) as HTMLElement[];\n this.container.style.contain = 'layout';\n this.resizeObserver.observe(this.container);\n this.gridItems.forEach((item) => this.resizeObserver.observe(item));\n\n this.resizeAllItems();\n }\n\n public destroy() {\n if (!this.container) return;\n\n this.resizeObserver.unobserve(this.container);\n this.gridItems.forEach((item) => this.resizeObserver.unobserve(item));\n\n this.container.style.contain = '';\n this.container.style.alignItems = '';\n this.gridItems.forEach((item) => {\n const { style } = item;\n\n style.gridRowEnd = '';\n });\n }\n}\n\nexport default MasonrySimple;\n"],"names":[],"version":3,"file":"index.d.ts.map"}
1
+ {"mappings":"AAAA,qBAAM,aAAa;gBAQL,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;KAAO;IAkCvD,IAAI,IAAI,IAAI;IAyCZ,OAAO,IAAI,IAAI;CAcvB;AAED,eAAe,aAAa,CAAC","sources":["src/src/index.ts","src/index.ts"],"sourcesContent":[null,"class MasonrySimple {\n private container: HTMLElement | null;\n private gridItems: HTMLElement[] = [];\n private rowHeight = 1;\n private rowGap = 0;\n private resizeObserver: ResizeObserver | null = null;\n private abortController: AbortController | null = null;\n\n constructor(options: { container?: HTMLElement | string } = {}) {\n this.container =\n options.container instanceof HTMLElement\n ? options.container\n : typeof options.container === 'string'\n ? document.querySelector(options.container)\n : document.querySelector('.masonry') || null;\n }\n\n private handleResize(): void {\n const callback = (): void => this.resizeAllItems();\n\n (\n window as Window &\n typeof globalThis & {\n requestIdleCallback: (\n callback: IdleRequestCallback,\n options?: IdleRequestOptions,\n ) => void;\n }\n ).requestIdleCallback(callback, { timeout: 200 });\n }\n\n private resizeAllItems(): void {\n if (!this.container) return;\n\n this.container.style.alignItems = 'start';\n this.gridItems.forEach((item) => {\n const rowSpan = Math.ceil((item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap));\n\n item.style.gridRowEnd = `span ${rowSpan}`;\n });\n }\n\n public init(): void {\n if (!this.container) return;\n\n this.setupAbortController();\n this.setupResizeObserver();\n this.initializeContainerStyles();\n this.initializeGridItems();\n this.resizeAllItems();\n }\n\n private setupAbortController(): void {\n this.abortController = new AbortController();\n this.abortController.signal.addEventListener('abort', () => {\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n });\n }\n\n private setupResizeObserver(): void {\n this.resizeObserver = new ResizeObserver(() => this.handleResize());\n\n if (this.resizeObserver) {\n this.resizeObserver.observe(this.container!);\n this.gridItems.forEach((item) => this.resizeObserver!.observe(item));\n }\n }\n\n private initializeContainerStyles(): void {\n const computedStyle = getComputedStyle(this.container!);\n\n this.rowGap = parseInt(computedStyle.rowGap, 10) || 0;\n this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;\n\n this.container!.style.contain = 'layout';\n }\n\n private initializeGridItems(): void {\n this.gridItems = Array.from(this.container!.children) as HTMLElement[];\n }\n\n public destroy(): void {\n if (!this.container || !this.abortController || !this.resizeObserver) return;\n\n this.abortController.abort();\n\n this.container.style.contain = '';\n this.container.style.alignItems = '';\n this.gridItems.forEach((item) => {\n item.style.gridRowEnd = '';\n });\n\n this.abortController = null;\n this.resizeObserver = null;\n }\n}\n\nexport default MasonrySimple;\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.js CHANGED
@@ -11,50 +11,68 @@ $parcel$defineInteropFlag(module.exports);
11
11
 
12
12
  $parcel$export(module.exports, "default", function () { return $a196c1ed25598f0e$export$2e2bcd8739ae039; });
13
13
  class $a196c1ed25598f0e$var$MasonrySimple {
14
- container = null;
15
- gridItems = [];
16
- rowHeight = 1;
17
- rowGap = 0;
18
- resizeTimeout = null;
19
- resizeObserver;
20
14
  constructor(options = {}){
21
- this.container = options.container instanceof HTMLElement ? options.container : document.querySelector(options.container || ".masonry");
22
- this.resizeObserver = new ResizeObserver(()=>this.handleResize());
15
+ this.gridItems = [];
16
+ this.rowHeight = 1;
17
+ this.rowGap = 0;
18
+ this.resizeObserver = null;
19
+ this.abortController = null;
20
+ this.container = options.container instanceof HTMLElement ? options.container : typeof options.container === "string" ? document.querySelector(options.container) : document.querySelector(".masonry") || null;
23
21
  }
24
22
  handleResize() {
25
- if (this.resizeTimeout !== null) window.cancelAnimationFrame(this.resizeTimeout);
26
- this.resizeTimeout = window.requestAnimationFrame(()=>this.resizeAllItems());
23
+ const callback = ()=>this.resizeAllItems();
24
+ window.requestIdleCallback(callback, {
25
+ timeout: 200
26
+ });
27
27
  }
28
28
  resizeAllItems() {
29
29
  if (!this.container) return;
30
30
  this.container.style.alignItems = "start";
31
31
  this.gridItems.forEach((item)=>{
32
32
  const rowSpan = Math.ceil((item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap));
33
- const { style: style } = item;
34
- style.gridRowEnd = `span ${rowSpan}`;
33
+ item.style.gridRowEnd = `span ${rowSpan}`;
35
34
  });
36
35
  }
37
36
  init() {
38
37
  if (!this.container) return;
38
+ this.setupAbortController();
39
+ this.setupResizeObserver();
40
+ this.initializeContainerStyles();
41
+ this.initializeGridItems();
42
+ this.resizeAllItems();
43
+ }
44
+ setupAbortController() {
45
+ this.abortController = new AbortController();
46
+ this.abortController.signal.addEventListener("abort", ()=>{
47
+ if (this.resizeObserver) this.resizeObserver.disconnect();
48
+ });
49
+ }
50
+ setupResizeObserver() {
51
+ this.resizeObserver = new ResizeObserver(()=>this.handleResize());
52
+ if (this.resizeObserver) {
53
+ this.resizeObserver.observe(this.container);
54
+ this.gridItems.forEach((item)=>this.resizeObserver.observe(item));
55
+ }
56
+ }
57
+ initializeContainerStyles() {
39
58
  const computedStyle = getComputedStyle(this.container);
40
- this.rowGap = parseInt(computedStyle.rowGap, 10);
59
+ this.rowGap = parseInt(computedStyle.rowGap, 10) || 0;
41
60
  this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;
42
- this.gridItems = Array.from(this.container.children);
43
61
  this.container.style.contain = "layout";
44
- this.resizeObserver.observe(this.container);
45
- this.gridItems.forEach((item)=>this.resizeObserver.observe(item));
46
- this.resizeAllItems();
62
+ }
63
+ initializeGridItems() {
64
+ this.gridItems = Array.from(this.container.children);
47
65
  }
48
66
  destroy() {
49
- if (!this.container) return;
50
- this.resizeObserver.unobserve(this.container);
51
- this.gridItems.forEach((item)=>this.resizeObserver.unobserve(item));
67
+ if (!this.container || !this.abortController || !this.resizeObserver) return;
68
+ this.abortController.abort();
52
69
  this.container.style.contain = "";
53
70
  this.container.style.alignItems = "";
54
71
  this.gridItems.forEach((item)=>{
55
- const { style: style } = item;
56
- style.gridRowEnd = "";
72
+ item.style.gridRowEnd = "";
57
73
  });
74
+ this.abortController = null;
75
+ this.resizeObserver = null;
58
76
  }
59
77
  }
60
78
  var $a196c1ed25598f0e$export$2e2bcd8739ae039 = $a196c1ed25598f0e$var$MasonrySimple;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;;;;;AAAA,MAAM;IACa,YAAgC,KAAK;IAE9C,YAA2B,EAAE,CAAC;IAE9B,YAAoB,EAAE;IAEtB,SAAiB,EAAE;IAEnB,gBAA+B,KAAK;IAEpC,eAA+B;IAEvC,YAAY,UAAgD,CAAC,CAAC,CAAE;QAC9D,IAAI,CAAC,SAAS,GAAG,QAAQ,SAAS,YAAY,cAC1C,QAAQ,SAAS,GACjB,SAAS,aAAa,CAAC,QAAQ,SAAS,IAAI;QAEhD,IAAI,CAAC,cAAc,GAAG,IAAI,eAAe,IAAM,IAAI,CAAC,YAAY;IAClE;IAEQ,eAAe;QACrB,IAAI,IAAI,CAAC,aAAa,KAAK,MACzB,OAAO,oBAAoB,CAAC,IAAI,CAAC,aAAa;QAGhD,IAAI,CAAC,aAAa,GAAG,OAAO,qBAAqB,CAAC,IAAM,IAAI,CAAC,cAAc;IAC7E;IAEQ,iBAAiB;QACvB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,UAAU,KAAK,IAAI,CACvB,AAAC,CAAA,KAAK,YAAY,GAAG,IAAI,CAAC,MAAM,AAAD,IAAM,CAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,AAAD;YAGlE,MAAM,SAAE,KAAK,EAAE,GAAG;YAElB,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC;QACtC;IACF;IAEO,OAAO;QACZ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,MAAM,gBAAgB,iBAAiB,IAAI,CAAC,SAAS;QAErD,IAAI,CAAC,MAAM,GAAG,SAAS,cAAc,MAAM,EAAE;QAC7C,IAAI,CAAC,SAAS,GAAG,SAAS,cAAc,YAAY,EAAE,OAAO,IAAI,CAAC,SAAS;QAE3E,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ;QACnD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS;QAC1C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAS,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;QAE7D,IAAI,CAAC,cAAc;IACrB;IAEO,UAAU;QACf,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS;QAC5C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAS,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;QAE/D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG;QAC/B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,SAAE,KAAK,EAAE,GAAG;YAElB,MAAM,UAAU,GAAG;QACrB;IACF;AACF;IAEA,2CAAe","sources":["src/index.ts"],"sourcesContent":["class MasonrySimple {\n private readonly container: HTMLElement | null = null;\n\n private gridItems: HTMLElement[] = [];\n\n private rowHeight: number = 1;\n\n private rowGap: number = 0;\n\n private resizeTimeout: number | null = null;\n\n private resizeObserver: ResizeObserver;\n\n constructor(options: { container?: HTMLElement | string } = {}) {\n this.container = options.container instanceof HTMLElement\n ? options.container\n : document.querySelector(options.container || '.masonry') as HTMLElement;\n\n this.resizeObserver = new ResizeObserver(() => this.handleResize());\n }\n\n private handleResize() {\n if (this.resizeTimeout !== null) {\n window.cancelAnimationFrame(this.resizeTimeout);\n }\n\n this.resizeTimeout = window.requestAnimationFrame(() => this.resizeAllItems());\n }\n\n private resizeAllItems() {\n if (!this.container) return;\n\n this.container.style.alignItems = 'start';\n this.gridItems.forEach((item) => {\n const rowSpan = Math.ceil(\n (item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap),\n );\n\n const { style } = item;\n\n style.gridRowEnd = `span ${rowSpan}`;\n });\n }\n\n public init() {\n if (!this.container) return;\n\n const computedStyle = getComputedStyle(this.container);\n\n this.rowGap = parseInt(computedStyle.rowGap, 10);\n this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;\n\n this.gridItems = Array.from(this.container.children) as HTMLElement[];\n this.container.style.contain = 'layout';\n this.resizeObserver.observe(this.container);\n this.gridItems.forEach((item) => this.resizeObserver.observe(item));\n\n this.resizeAllItems();\n }\n\n public destroy() {\n if (!this.container) return;\n\n this.resizeObserver.unobserve(this.container);\n this.gridItems.forEach((item) => this.resizeObserver.unobserve(item));\n\n this.container.style.contain = '';\n this.container.style.alignItems = '';\n this.gridItems.forEach((item) => {\n const { style } = item;\n\n style.gridRowEnd = '';\n });\n }\n}\n\nexport default MasonrySimple;\n"],"names":[],"version":3,"file":"index.js.map"}
1
+ {"mappings":";;;;;;;;;;;;AAAA,MAAM;IAQJ,YAAY,UAAgD,CAAC,CAAC,CAAE;aANxD,YAA2B,EAAE;aAC7B,YAAY;aACZ,SAAS;aACT,iBAAwC;aACxC,kBAA0C;QAGhD,IAAI,CAAC,SAAS,GACZ,QAAQ,SAAS,YAAY,cACzB,QAAQ,SAAS,GACjB,OAAO,QAAQ,SAAS,KAAK,WAC3B,SAAS,aAAa,CAAC,QAAQ,SAAS,IACxC,SAAS,aAAa,CAAC,eAAe;IAChD;IAEQ,eAAqB;QAC3B,MAAM,WAAW,IAAY,IAAI,CAAC,cAAc;QAG9C,OAOA,mBAAmB,CAAC,UAAU;YAAE,SAAS;QAAI;IACjD;IAEQ,iBAAuB;QAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,UAAU,KAAK,IAAI,CAAC,AAAC,CAAA,KAAK,YAAY,GAAG,IAAI,CAAC,MAAM,AAAD,IAAM,CAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,AAAD;YAE1F,KAAK,KAAK,CAAC,UAAU,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC;QAC3C;IACF;IAEO,OAAa;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,IAAI,CAAC,oBAAoB;QACzB,IAAI,CAAC,mBAAmB;QACxB,IAAI,CAAC,yBAAyB;QAC9B,IAAI,CAAC,mBAAmB;QACxB,IAAI,CAAC,cAAc;IACrB;IAEQ,uBAA6B;QACnC,IAAI,CAAC,eAAe,GAAG,IAAI;QAC3B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS;YACpD,IAAI,IAAI,CAAC,cAAc,EACrB,IAAI,CAAC,cAAc,CAAC,UAAU;QAElC;IACF;IAEQ,sBAA4B;QAClC,IAAI,CAAC,cAAc,GAAG,IAAI,eAAe,IAAM,IAAI,CAAC,YAAY;QAEhE,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS;YAC1C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAS,IAAI,CAAC,cAAc,CAAE,OAAO,CAAC;QAChE;IACF;IAEQ,4BAAkC;QACxC,MAAM,gBAAgB,iBAAiB,IAAI,CAAC,SAAS;QAErD,IAAI,CAAC,MAAM,GAAG,SAAS,cAAc,MAAM,EAAE,OAAO;QACpD,IAAI,CAAC,SAAS,GAAG,SAAS,cAAc,YAAY,EAAE,OAAO,IAAI,CAAC,SAAS;QAE3E,IAAI,CAAC,SAAS,CAAE,KAAK,CAAC,OAAO,GAAG;IAClC;IAEQ,sBAA4B;QAClC,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAE,QAAQ;IACtD;IAEO,UAAgB;QACrB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;QAEtE,IAAI,CAAC,eAAe,CAAC,KAAK;QAE1B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG;QAC/B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtB,KAAK,KAAK,CAAC,UAAU,GAAG;QAC1B;QAEA,IAAI,CAAC,eAAe,GAAG;QACvB,IAAI,CAAC,cAAc,GAAG;IACxB;AACF;IAEA,2CAAe","sources":["src/index.ts"],"sourcesContent":["class MasonrySimple {\n private container: HTMLElement | null;\n private gridItems: HTMLElement[] = [];\n private rowHeight = 1;\n private rowGap = 0;\n private resizeObserver: ResizeObserver | null = null;\n private abortController: AbortController | null = null;\n\n constructor(options: { container?: HTMLElement | string } = {}) {\n this.container =\n options.container instanceof HTMLElement\n ? options.container\n : typeof options.container === 'string'\n ? document.querySelector(options.container)\n : document.querySelector('.masonry') || null;\n }\n\n private handleResize(): void {\n const callback = (): void => this.resizeAllItems();\n\n (\n window as Window &\n typeof globalThis & {\n requestIdleCallback: (\n callback: IdleRequestCallback,\n options?: IdleRequestOptions,\n ) => void;\n }\n ).requestIdleCallback(callback, { timeout: 200 });\n }\n\n private resizeAllItems(): void {\n if (!this.container) return;\n\n this.container.style.alignItems = 'start';\n this.gridItems.forEach((item) => {\n const rowSpan = Math.ceil((item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap));\n\n item.style.gridRowEnd = `span ${rowSpan}`;\n });\n }\n\n public init(): void {\n if (!this.container) return;\n\n this.setupAbortController();\n this.setupResizeObserver();\n this.initializeContainerStyles();\n this.initializeGridItems();\n this.resizeAllItems();\n }\n\n private setupAbortController(): void {\n this.abortController = new AbortController();\n this.abortController.signal.addEventListener('abort', () => {\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n });\n }\n\n private setupResizeObserver(): void {\n this.resizeObserver = new ResizeObserver(() => this.handleResize());\n\n if (this.resizeObserver) {\n this.resizeObserver.observe(this.container!);\n this.gridItems.forEach((item) => this.resizeObserver!.observe(item));\n }\n }\n\n private initializeContainerStyles(): void {\n const computedStyle = getComputedStyle(this.container!);\n\n this.rowGap = parseInt(computedStyle.rowGap, 10) || 0;\n this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;\n\n this.container!.style.contain = 'layout';\n }\n\n private initializeGridItems(): void {\n this.gridItems = Array.from(this.container!.children) as HTMLElement[];\n }\n\n public destroy(): void {\n if (!this.container || !this.abortController || !this.resizeObserver) return;\n\n this.abortController.abort();\n\n this.container.style.contain = '';\n this.container.style.alignItems = '';\n this.gridItems.forEach((item) => {\n item.style.gridRowEnd = '';\n });\n\n this.abortController = null;\n this.resizeObserver = null;\n }\n}\n\nexport default MasonrySimple;\n"],"names":[],"version":3,"file":"index.js.map"}
@@ -1,48 +1,66 @@
1
1
  class $643fcf18b2d2e76f$var$MasonrySimple {
2
- container = null;
3
- gridItems = [];
4
- rowHeight = 1;
5
- rowGap = 0;
6
- resizeTimeout = null;
7
- resizeObserver;
8
2
  constructor(options = {}){
9
- this.container = options.container instanceof HTMLElement ? options.container : document.querySelector(options.container || ".masonry");
10
- this.resizeObserver = new ResizeObserver(()=>this.handleResize());
3
+ this.gridItems = [];
4
+ this.rowHeight = 1;
5
+ this.rowGap = 0;
6
+ this.resizeObserver = null;
7
+ this.abortController = null;
8
+ this.container = options.container instanceof HTMLElement ? options.container : typeof options.container === "string" ? document.querySelector(options.container) : document.querySelector(".masonry") || null;
11
9
  }
12
10
  handleResize() {
13
- if (this.resizeTimeout !== null) window.cancelAnimationFrame(this.resizeTimeout);
14
- this.resizeTimeout = window.requestAnimationFrame(()=>this.resizeAllItems());
11
+ const callback = ()=>this.resizeAllItems();
12
+ window.requestIdleCallback(callback, {
13
+ timeout: 200
14
+ });
15
15
  }
16
16
  resizeAllItems() {
17
17
  if (!this.container) return;
18
18
  this.container.style.alignItems = "start";
19
19
  this.gridItems.forEach((item)=>{
20
20
  const rowSpan = Math.ceil((item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap));
21
- const { style: style } = item;
22
- style.gridRowEnd = `span ${rowSpan}`;
21
+ item.style.gridRowEnd = `span ${rowSpan}`;
23
22
  });
24
23
  }
25
24
  init() {
26
25
  if (!this.container) return;
26
+ this.setupAbortController();
27
+ this.setupResizeObserver();
28
+ this.initializeContainerStyles();
29
+ this.initializeGridItems();
30
+ this.resizeAllItems();
31
+ }
32
+ setupAbortController() {
33
+ this.abortController = new AbortController();
34
+ this.abortController.signal.addEventListener("abort", ()=>{
35
+ if (this.resizeObserver) this.resizeObserver.disconnect();
36
+ });
37
+ }
38
+ setupResizeObserver() {
39
+ this.resizeObserver = new ResizeObserver(()=>this.handleResize());
40
+ if (this.resizeObserver) {
41
+ this.resizeObserver.observe(this.container);
42
+ this.gridItems.forEach((item)=>this.resizeObserver.observe(item));
43
+ }
44
+ }
45
+ initializeContainerStyles() {
27
46
  const computedStyle = getComputedStyle(this.container);
28
- this.rowGap = parseInt(computedStyle.rowGap, 10);
47
+ this.rowGap = parseInt(computedStyle.rowGap, 10) || 0;
29
48
  this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;
30
- this.gridItems = Array.from(this.container.children);
31
49
  this.container.style.contain = "layout";
32
- this.resizeObserver.observe(this.container);
33
- this.gridItems.forEach((item)=>this.resizeObserver.observe(item));
34
- this.resizeAllItems();
50
+ }
51
+ initializeGridItems() {
52
+ this.gridItems = Array.from(this.container.children);
35
53
  }
36
54
  destroy() {
37
- if (!this.container) return;
38
- this.resizeObserver.unobserve(this.container);
39
- this.gridItems.forEach((item)=>this.resizeObserver.unobserve(item));
55
+ if (!this.container || !this.abortController || !this.resizeObserver) return;
56
+ this.abortController.abort();
40
57
  this.container.style.contain = "";
41
58
  this.container.style.alignItems = "";
42
59
  this.gridItems.forEach((item)=>{
43
- const { style: style } = item;
44
- style.gridRowEnd = "";
60
+ item.style.gridRowEnd = "";
45
61
  });
62
+ this.abortController = null;
63
+ this.resizeObserver = null;
46
64
  }
47
65
  }
48
66
  var $643fcf18b2d2e76f$export$2e2bcd8739ae039 = $643fcf18b2d2e76f$var$MasonrySimple;
@@ -1 +1 @@
1
- {"mappings":"AAAA,MAAM;IACa,YAAgC,KAAK;IAE9C,YAA2B,EAAE,CAAC;IAE9B,YAAoB,EAAE;IAEtB,SAAiB,EAAE;IAEnB,gBAA+B,KAAK;IAEpC,eAA+B;IAEvC,YAAY,UAAgD,CAAC,CAAC,CAAE;QAC9D,IAAI,CAAC,SAAS,GAAG,QAAQ,SAAS,YAAY,cAC1C,QAAQ,SAAS,GACjB,SAAS,aAAa,CAAC,QAAQ,SAAS,IAAI;QAEhD,IAAI,CAAC,cAAc,GAAG,IAAI,eAAe,IAAM,IAAI,CAAC,YAAY;IAClE;IAEQ,eAAe;QACrB,IAAI,IAAI,CAAC,aAAa,KAAK,MACzB,OAAO,oBAAoB,CAAC,IAAI,CAAC,aAAa;QAGhD,IAAI,CAAC,aAAa,GAAG,OAAO,qBAAqB,CAAC,IAAM,IAAI,CAAC,cAAc;IAC7E;IAEQ,iBAAiB;QACvB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,UAAU,KAAK,IAAI,CACvB,AAAC,CAAA,KAAK,YAAY,GAAG,IAAI,CAAC,MAAM,AAAD,IAAM,CAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,AAAD;YAGlE,MAAM,SAAE,KAAK,EAAE,GAAG;YAElB,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC;QACtC;IACF;IAEO,OAAO;QACZ,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,MAAM,gBAAgB,iBAAiB,IAAI,CAAC,SAAS;QAErD,IAAI,CAAC,MAAM,GAAG,SAAS,cAAc,MAAM,EAAE;QAC7C,IAAI,CAAC,SAAS,GAAG,SAAS,cAAc,YAAY,EAAE,OAAO,IAAI,CAAC,SAAS;QAE3E,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ;QACnD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG;QAC/B,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS;QAC1C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAS,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;QAE7D,IAAI,CAAC,cAAc;IACrB;IAEO,UAAU;QACf,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS;QAC5C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAS,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;QAE/D,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG;QAC/B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,SAAE,KAAK,EAAE,GAAG;YAElB,MAAM,UAAU,GAAG;QACrB;IACF;AACF;IAEA,2CAAe","sources":["src/index.ts"],"sourcesContent":["class MasonrySimple {\n private readonly container: HTMLElement | null = null;\n\n private gridItems: HTMLElement[] = [];\n\n private rowHeight: number = 1;\n\n private rowGap: number = 0;\n\n private resizeTimeout: number | null = null;\n\n private resizeObserver: ResizeObserver;\n\n constructor(options: { container?: HTMLElement | string } = {}) {\n this.container = options.container instanceof HTMLElement\n ? options.container\n : document.querySelector(options.container || '.masonry') as HTMLElement;\n\n this.resizeObserver = new ResizeObserver(() => this.handleResize());\n }\n\n private handleResize() {\n if (this.resizeTimeout !== null) {\n window.cancelAnimationFrame(this.resizeTimeout);\n }\n\n this.resizeTimeout = window.requestAnimationFrame(() => this.resizeAllItems());\n }\n\n private resizeAllItems() {\n if (!this.container) return;\n\n this.container.style.alignItems = 'start';\n this.gridItems.forEach((item) => {\n const rowSpan = Math.ceil(\n (item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap),\n );\n\n const { style } = item;\n\n style.gridRowEnd = `span ${rowSpan}`;\n });\n }\n\n public init() {\n if (!this.container) return;\n\n const computedStyle = getComputedStyle(this.container);\n\n this.rowGap = parseInt(computedStyle.rowGap, 10);\n this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;\n\n this.gridItems = Array.from(this.container.children) as HTMLElement[];\n this.container.style.contain = 'layout';\n this.resizeObserver.observe(this.container);\n this.gridItems.forEach((item) => this.resizeObserver.observe(item));\n\n this.resizeAllItems();\n }\n\n public destroy() {\n if (!this.container) return;\n\n this.resizeObserver.unobserve(this.container);\n this.gridItems.forEach((item) => this.resizeObserver.unobserve(item));\n\n this.container.style.contain = '';\n this.container.style.alignItems = '';\n this.gridItems.forEach((item) => {\n const { style } = item;\n\n style.gridRowEnd = '';\n });\n }\n}\n\nexport default MasonrySimple;\n"],"names":[],"version":3,"file":"index.module.js.map"}
1
+ {"mappings":"AAAA,MAAM;IAQJ,YAAY,UAAgD,CAAC,CAAC,CAAE;aANxD,YAA2B,EAAE;aAC7B,YAAY;aACZ,SAAS;aACT,iBAAwC;aACxC,kBAA0C;QAGhD,IAAI,CAAC,SAAS,GACZ,QAAQ,SAAS,YAAY,cACzB,QAAQ,SAAS,GACjB,OAAO,QAAQ,SAAS,KAAK,WAC3B,SAAS,aAAa,CAAC,QAAQ,SAAS,IACxC,SAAS,aAAa,CAAC,eAAe;IAChD;IAEQ,eAAqB;QAC3B,MAAM,WAAW,IAAY,IAAI,CAAC,cAAc;QAG9C,OAOA,mBAAmB,CAAC,UAAU;YAAE,SAAS;QAAI;IACjD;IAEQ,iBAAuB;QAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,UAAU,KAAK,IAAI,CAAC,AAAC,CAAA,KAAK,YAAY,GAAG,IAAI,CAAC,MAAM,AAAD,IAAM,CAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,AAAD;YAE1F,KAAK,KAAK,CAAC,UAAU,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC;QAC3C;IACF;IAEO,OAAa;QAClB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;QAErB,IAAI,CAAC,oBAAoB;QACzB,IAAI,CAAC,mBAAmB;QACxB,IAAI,CAAC,yBAAyB;QAC9B,IAAI,CAAC,mBAAmB;QACxB,IAAI,CAAC,cAAc;IACrB;IAEQ,uBAA6B;QACnC,IAAI,CAAC,eAAe,GAAG,IAAI;QAC3B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,gBAAgB,CAAC,SAAS;YACpD,IAAI,IAAI,CAAC,cAAc,EACrB,IAAI,CAAC,cAAc,CAAC,UAAU;QAElC;IACF;IAEQ,sBAA4B;QAClC,IAAI,CAAC,cAAc,GAAG,IAAI,eAAe,IAAM,IAAI,CAAC,YAAY;QAEhE,IAAI,IAAI,CAAC,cAAc,EAAE;YACvB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS;YAC1C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,OAAS,IAAI,CAAC,cAAc,CAAE,OAAO,CAAC;QAChE;IACF;IAEQ,4BAAkC;QACxC,MAAM,gBAAgB,iBAAiB,IAAI,CAAC,SAAS;QAErD,IAAI,CAAC,MAAM,GAAG,SAAS,cAAc,MAAM,EAAE,OAAO;QACpD,IAAI,CAAC,SAAS,GAAG,SAAS,cAAc,YAAY,EAAE,OAAO,IAAI,CAAC,SAAS;QAE3E,IAAI,CAAC,SAAS,CAAE,KAAK,CAAC,OAAO,GAAG;IAClC;IAEQ,sBAA4B;QAClC,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAE,QAAQ;IACtD;IAEO,UAAgB;QACrB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;QAEtE,IAAI,CAAC,eAAe,CAAC,KAAK;QAE1B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG;QAC/B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,GAAG;QAClC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACtB,KAAK,KAAK,CAAC,UAAU,GAAG;QAC1B;QAEA,IAAI,CAAC,eAAe,GAAG;QACvB,IAAI,CAAC,cAAc,GAAG;IACxB;AACF;IAEA,2CAAe","sources":["src/index.ts"],"sourcesContent":["class MasonrySimple {\n private container: HTMLElement | null;\n private gridItems: HTMLElement[] = [];\n private rowHeight = 1;\n private rowGap = 0;\n private resizeObserver: ResizeObserver | null = null;\n private abortController: AbortController | null = null;\n\n constructor(options: { container?: HTMLElement | string } = {}) {\n this.container =\n options.container instanceof HTMLElement\n ? options.container\n : typeof options.container === 'string'\n ? document.querySelector(options.container)\n : document.querySelector('.masonry') || null;\n }\n\n private handleResize(): void {\n const callback = (): void => this.resizeAllItems();\n\n (\n window as Window &\n typeof globalThis & {\n requestIdleCallback: (\n callback: IdleRequestCallback,\n options?: IdleRequestOptions,\n ) => void;\n }\n ).requestIdleCallback(callback, { timeout: 200 });\n }\n\n private resizeAllItems(): void {\n if (!this.container) return;\n\n this.container.style.alignItems = 'start';\n this.gridItems.forEach((item) => {\n const rowSpan = Math.ceil((item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap));\n\n item.style.gridRowEnd = `span ${rowSpan}`;\n });\n }\n\n public init(): void {\n if (!this.container) return;\n\n this.setupAbortController();\n this.setupResizeObserver();\n this.initializeContainerStyles();\n this.initializeGridItems();\n this.resizeAllItems();\n }\n\n private setupAbortController(): void {\n this.abortController = new AbortController();\n this.abortController.signal.addEventListener('abort', () => {\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n }\n });\n }\n\n private setupResizeObserver(): void {\n this.resizeObserver = new ResizeObserver(() => this.handleResize());\n\n if (this.resizeObserver) {\n this.resizeObserver.observe(this.container!);\n this.gridItems.forEach((item) => this.resizeObserver!.observe(item));\n }\n }\n\n private initializeContainerStyles(): void {\n const computedStyle = getComputedStyle(this.container!);\n\n this.rowGap = parseInt(computedStyle.rowGap, 10) || 0;\n this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;\n\n this.container!.style.contain = 'layout';\n }\n\n private initializeGridItems(): void {\n this.gridItems = Array.from(this.container!.children) as HTMLElement[];\n }\n\n public destroy(): void {\n if (!this.container || !this.abortController || !this.resizeObserver) return;\n\n this.abortController.abort();\n\n this.container.style.contain = '';\n this.container.style.alignItems = '';\n this.gridItems.forEach((item) => {\n item.style.gridRowEnd = '';\n });\n\n this.abortController = null;\n this.resizeObserver = null;\n }\n}\n\nexport default MasonrySimple;\n"],"names":[],"version":3,"file":"index.module.js.map"}
@@ -0,0 +1,63 @@
1
+ import globals from 'globals';
2
+ import eslintPlugin from '@eslint/js';
3
+ import typescriptPlugin from '@typescript-eslint/eslint-plugin';
4
+ import typescriptParser from '@typescript-eslint/parser';
5
+ import prettierConfig from 'eslint-config-prettier';
6
+ import importPlugin from 'eslint-plugin-import';
7
+
8
+ /** @type {import("eslint").Linter.FlatConfig[]} */
9
+ export default [
10
+ {
11
+ ignores: ['node_modules', 'dist', '.parcel', '.parcel-cache'],
12
+ },
13
+ {
14
+ files: ['**/*.{js,jsx,ts,tsx}'],
15
+ languageOptions: {
16
+ ecmaVersion: 'latest',
17
+ sourceType: 'module',
18
+ parser: typescriptParser,
19
+ globals: {
20
+ ...globals.browser,
21
+ ...globals.es2022,
22
+ },
23
+ parserOptions: {
24
+ project: './tsconfig.json',
25
+ allowJs: true,
26
+ },
27
+ },
28
+ plugins: {
29
+ '@typescript-eslint': typescriptPlugin,
30
+ eslint: eslintPlugin,
31
+ import: importPlugin,
32
+ },
33
+ rules: {
34
+ ...eslintPlugin.configs.recommended.rules,
35
+ ...typescriptPlugin.configs.recommended.rules,
36
+ ...typescriptPlugin.configs['recommended-requiring-type-checking'].rules,
37
+ '@typescript-eslint/no-unused-vars': 'error',
38
+ '@typescript-eslint/explicit-function-return-type': 'warn',
39
+ '@typescript-eslint/no-explicit-any': 'warn',
40
+ 'import/order': [
41
+ 'error',
42
+ {
43
+ groups: [['builtin', 'external', 'internal']],
44
+ 'newlines-between': 'always',
45
+ },
46
+ ],
47
+ 'import/no-unresolved': 'error',
48
+ 'import/no-duplicates': 'error',
49
+ 'max-len': [
50
+ 'error',
51
+ {
52
+ code: 100,
53
+ ignoreUrls: true,
54
+ ignoreStrings: true,
55
+ ignoreTemplateLiterals: true,
56
+ ignoreComments: true,
57
+ },
58
+ ],
59
+ 'linebreak-style': ['error', 'unix'],
60
+ },
61
+ },
62
+ prettierConfig,
63
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "masonry-simple",
3
- "version": "3.2.1",
3
+ "version": "4.0.0",
4
4
  "description": "MasonrySimple implements a simple system for placing masonry style elements using CSS Grid. Masonry placement is used for dynamic grids where elements may have different heights and need to be placed neatly without gaps.",
5
5
  "author": "ux-ui.pro",
6
6
  "license": "MIT",
@@ -17,7 +17,9 @@
17
17
  "clean": "rm -rf dist .parcel-cache",
18
18
  "build": "yarn clean && parcel build",
19
19
  "lint:js": "eslint **/*.{ts,js}",
20
- "lintfix": "yarn lint:js --fix"
20
+ "lint:fix:js": "eslint **/*.{ts,js} --fix",
21
+ "format:js": "prettier --write **/*.{ts,js}",
22
+ "lint:fix": "yarn lint:fix:js && yarn format:js"
21
23
  },
22
24
  "browserslist": "> 0.5%, last 2 versions, not dead",
23
25
  "source": "src/index.ts",
@@ -25,15 +27,18 @@
25
27
  "module": "dist/index.module.js",
26
28
  "types": "dist/index.d.ts",
27
29
  "devDependencies": {
28
- "@parcel/packager-ts": "2.12.0",
29
- "@parcel/transformer-typescript-types": "2.12.0",
30
- "@typescript-eslint/eslint-plugin": "^7.11.0",
31
- "@typescript-eslint/parser": "^7.11.0",
32
- "eslint": "^7.32.0 || ^8.57.0",
33
- "eslint-config-airbnb-base": "^15.0.0",
34
- "eslint-plugin-import": "^2.29.1",
30
+ "@eslint/js": "^9.12.0",
31
+ "@parcel/packager-ts": "^2.12.0",
32
+ "@parcel/transformer-typescript-types": "^2.12.0",
33
+ "@typescript-eslint/eslint-plugin": "^8.9.0",
34
+ "@typescript-eslint/parser": "^8.9.0",
35
+ "eslint": "^9.12.0",
36
+ "eslint-config-prettier": "^9.1.0",
37
+ "eslint-plugin-import": "^2.31.0",
38
+ "globals": "^15.11.0",
35
39
  "parcel": "^2.12.0",
36
- "typescript": "^5.4.5"
40
+ "prettier": "^3.3.3",
41
+ "typescript": "5.4.5"
37
42
  },
38
43
  "keywords": [
39
44
  "masonry",
package/src/index.ts CHANGED
@@ -1,76 +1,99 @@
1
1
  class MasonrySimple {
2
- private readonly container: HTMLElement | null = null;
3
-
2
+ private container: HTMLElement | null;
4
3
  private gridItems: HTMLElement[] = [];
5
-
6
- private rowHeight: number = 1;
7
-
8
- private rowGap: number = 0;
9
-
10
- private resizeTimeout: number | null = null;
11
-
12
- private resizeObserver: ResizeObserver;
4
+ private rowHeight = 1;
5
+ private rowGap = 0;
6
+ private resizeObserver: ResizeObserver | null = null;
7
+ private abortController: AbortController | null = null;
13
8
 
14
9
  constructor(options: { container?: HTMLElement | string } = {}) {
15
- this.container = options.container instanceof HTMLElement
16
- ? options.container
17
- : document.querySelector(options.container || '.masonry') as HTMLElement;
18
-
19
- this.resizeObserver = new ResizeObserver(() => this.handleResize());
10
+ this.container =
11
+ options.container instanceof HTMLElement
12
+ ? options.container
13
+ : typeof options.container === 'string'
14
+ ? document.querySelector(options.container)
15
+ : document.querySelector('.masonry') || null;
20
16
  }
21
17
 
22
- private handleResize() {
23
- if (this.resizeTimeout !== null) {
24
- window.cancelAnimationFrame(this.resizeTimeout);
25
- }
26
-
27
- this.resizeTimeout = window.requestAnimationFrame(() => this.resizeAllItems());
18
+ private handleResize(): void {
19
+ const callback = (): void => this.resizeAllItems();
20
+
21
+ (
22
+ window as Window &
23
+ typeof globalThis & {
24
+ requestIdleCallback: (
25
+ callback: IdleRequestCallback,
26
+ options?: IdleRequestOptions,
27
+ ) => void;
28
+ }
29
+ ).requestIdleCallback(callback, { timeout: 200 });
28
30
  }
29
31
 
30
- private resizeAllItems() {
32
+ private resizeAllItems(): void {
31
33
  if (!this.container) return;
32
34
 
33
35
  this.container.style.alignItems = 'start';
34
36
  this.gridItems.forEach((item) => {
35
- const rowSpan = Math.ceil(
36
- (item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap),
37
- );
38
-
39
- const { style } = item;
37
+ const rowSpan = Math.ceil((item.clientHeight + this.rowGap) / (this.rowHeight + this.rowGap));
40
38
 
41
- style.gridRowEnd = `span ${rowSpan}`;
39
+ item.style.gridRowEnd = `span ${rowSpan}`;
42
40
  });
43
41
  }
44
42
 
45
- public init() {
43
+ public init(): void {
46
44
  if (!this.container) return;
47
45
 
48
- const computedStyle = getComputedStyle(this.container);
46
+ this.setupAbortController();
47
+ this.setupResizeObserver();
48
+ this.initializeContainerStyles();
49
+ this.initializeGridItems();
50
+ this.resizeAllItems();
51
+ }
52
+
53
+ private setupAbortController(): void {
54
+ this.abortController = new AbortController();
55
+ this.abortController.signal.addEventListener('abort', () => {
56
+ if (this.resizeObserver) {
57
+ this.resizeObserver.disconnect();
58
+ }
59
+ });
60
+ }
61
+
62
+ private setupResizeObserver(): void {
63
+ this.resizeObserver = new ResizeObserver(() => this.handleResize());
64
+
65
+ if (this.resizeObserver) {
66
+ this.resizeObserver.observe(this.container!);
67
+ this.gridItems.forEach((item) => this.resizeObserver!.observe(item));
68
+ }
69
+ }
49
70
 
50
- this.rowGap = parseInt(computedStyle.rowGap, 10);
71
+ private initializeContainerStyles(): void {
72
+ const computedStyle = getComputedStyle(this.container!);
73
+
74
+ this.rowGap = parseInt(computedStyle.rowGap, 10) || 0;
51
75
  this.rowHeight = parseInt(computedStyle.gridAutoRows, 10) || this.rowHeight;
52
76
 
53
- this.gridItems = Array.from(this.container.children) as HTMLElement[];
54
- this.container.style.contain = 'layout';
55
- this.resizeObserver.observe(this.container);
56
- this.gridItems.forEach((item) => this.resizeObserver.observe(item));
77
+ this.container!.style.contain = 'layout';
78
+ }
57
79
 
58
- this.resizeAllItems();
80
+ private initializeGridItems(): void {
81
+ this.gridItems = Array.from(this.container!.children) as HTMLElement[];
59
82
  }
60
83
 
61
- public destroy() {
62
- if (!this.container) return;
84
+ public destroy(): void {
85
+ if (!this.container || !this.abortController || !this.resizeObserver) return;
63
86
 
64
- this.resizeObserver.unobserve(this.container);
65
- this.gridItems.forEach((item) => this.resizeObserver.unobserve(item));
87
+ this.abortController.abort();
66
88
 
67
89
  this.container.style.contain = '';
68
90
  this.container.style.alignItems = '';
69
91
  this.gridItems.forEach((item) => {
70
- const { style } = item;
71
-
72
- style.gridRowEnd = '';
92
+ item.style.gridRowEnd = '';
73
93
  });
94
+
95
+ this.abortController = null;
96
+ this.resizeObserver = null;
74
97
  }
75
98
  }
76
99
 
package/tsconfig.json CHANGED
@@ -1,6 +1,13 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "isolatedModules": true,
4
- "target": "es2022"
4
+ "target": "ESNext",
5
+ "module": "ESNext",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "moduleResolution": "node",
11
+ "noImplicitAny": true
5
12
  }
6
13
  }
package/.eslintrc.json DELETED
@@ -1,26 +0,0 @@
1
- {
2
- "env": {
3
- "browser": true,
4
- "es2022": true
5
- },
6
- "extends": [
7
- "airbnb-base",
8
- "plugin:@typescript-eslint/recommended"
9
- ],
10
- "parser": "@typescript-eslint/parser",
11
- "parserOptions": {
12
- "ecmaVersion": "latest",
13
- "sourceType": "module",
14
- "project": "./tsconfig.json"
15
- },
16
- "plugins": ["@typescript-eslint"],
17
- "rules": {
18
- "max-len": [
19
- "off",
20
- {
21
- "code": 100,
22
- "ignoreUrls": true
23
- }
24
- ]
25
- }
26
- }