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.
- package/{.eslintignore → .prettierignore} +2 -1
- package/.prettierrc.json +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -22
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +40 -22
- package/dist/index.module.js.map +1 -1
- package/eslint.config.mjs +63 -0
- package/package.json +15 -10
- package/src/index.ts +66 -43
- package/tsconfig.json +8 -1
- package/.eslintrc.json +0 -26
package/.prettierrc.json
ADDED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,qBAAM,aAAa;
|
|
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.
|
|
22
|
-
this.
|
|
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
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
this.
|
|
62
|
+
}
|
|
63
|
+
initializeGridItems() {
|
|
64
|
+
this.gridItems = Array.from(this.container.children);
|
|
47
65
|
}
|
|
48
66
|
destroy() {
|
|
49
|
-
if (!this.container) return;
|
|
50
|
-
this.
|
|
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
|
-
|
|
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;
|
|
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"}
|
package/dist/index.module.js
CHANGED
|
@@ -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.
|
|
10
|
-
this.
|
|
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
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
this.
|
|
50
|
+
}
|
|
51
|
+
initializeGridItems() {
|
|
52
|
+
this.gridItems = Array.from(this.container.children);
|
|
35
53
|
}
|
|
36
54
|
destroy() {
|
|
37
|
-
if (!this.container) return;
|
|
38
|
-
this.
|
|
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
|
-
|
|
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;
|
package/dist/index.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,MAAM;
|
|
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
|
+
"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
|
-
"
|
|
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
|
-
"@
|
|
29
|
-
"@parcel/
|
|
30
|
-
"@typescript-
|
|
31
|
-
"@typescript-eslint/
|
|
32
|
-
"eslint": "^
|
|
33
|
-
"eslint
|
|
34
|
-
"eslint-
|
|
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
|
-
"
|
|
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
|
|
3
|
-
|
|
2
|
+
private container: HTMLElement | null;
|
|
4
3
|
private gridItems: HTMLElement[] = [];
|
|
5
|
-
|
|
6
|
-
private
|
|
7
|
-
|
|
8
|
-
private
|
|
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 =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
54
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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": "
|
|
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
|
-
}
|