react-stone-mason 2.0.1 → 2.0.2
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/dist/react-stone-mason.umd.js +2 -0
- package/package.json +14 -6
- package/.babelrc +0 -8
- package/build/index.js +0 -8
- package/build/index.js.map +0 -1
- package/build/react-stone-mason.js +0 -115
- package/build/react-stone-mason.js.map +0 -1
- package/build/types.js +0 -3
- package/build/types.js.map +0 -1
- package/build/util.js +0 -47
- package/build/util.js.map +0 -1
- package/dev/App.css +0 -33
- package/dev/App.tsx +0 -22
- package/dev/main.tsx +0 -10
- package/dev/util.tsx +0 -70
- package/dist/react-stone-mason.cjs.js +0 -1
- package/index.html +0 -4
- package/src/index.ts +0 -5
- package/src/react-stone-mason.css +0 -15
- package/src/react-stone-mason.tsx +0 -98
- package/src/types.ts +0 -23
- package/src/util.ts +0 -52
- package/tsconfig.json +0 -14
- package/vite.config.ts +0 -28
- package/webpack.config.js +0 -53
- /package/dist/{react-stone-mason.es.js → react-stone-mason.mjs} +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(l,m){typeof exports=="object"&&typeof module<"u"?module.exports=m(require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["react/jsx-runtime","react"],m):(l=typeof globalThis<"u"?globalThis:l||self,l["react-stone-mason"]=m(l.jsxRuntime,l.React))})(this,(function(l,m){"use strict";var p=document.createElement("style");p.textContent=`.mason-container{position:relative;overflow:hidden;--cell-width: 100%;box-sizing:border-box;margin:0;padding:0}.mason-container>*{box-sizing:inherit;display:inline-block;vertical-align:top;width:var(--cell-width)}
|
|
2
|
+
/*$vite$:1*/`,document.head.appendChild(p);function w(i){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const d in i)if(d!=="default"){const t=Object.getOwnPropertyDescriptor(i,d);Object.defineProperty(r,d,t.get?t:{enumerable:!0,get:()=>i[d]})}}return r.default=i,Object.freeze(r)}const b=w(m),C={childList:!0,subtree:!0},O=i=>{const r=Object.keys(i).find(t=>{var e;return!((e=i[t])!=null&&e.query)});return Object.keys(i).find(t=>{var o;const e=(o=i[t])==null?void 0:o.query;return e&&window.matchMedia(e).matches})||r},y=(i,r,d)=>{var n;const t=O(d);if(!t||!r)return;const e=+(((n=d[t])==null?void 0:n.columns)||1),o=Array.from(r.children),u=i.reduce((a,c)=>Math.min(a,o.indexOf(c)),o.length),s=Math.max(0,u-e);o.forEach((a,c)=>{if(c>=s){const f=c%e,h=o.slice(c-f,c-f+e),g=o[c-e],v=Number((g==null?void 0:g.getAttribute("data-debt"))||0),x=Math.max(...h.map(k=>k.getBoundingClientRect().height)),E=v+Math.ceil(x-a.getBoundingClientRect().height);a.setAttribute("data-debt",String(E)),a.style.transform=c>e-1?`translateY(-${v}px)`:""}}),window.requestAnimationFrame(()=>{var h;const a=o.slice(-1*e),c=Math.max(...a.map(g=>g.getBoundingClientRect().bottom)),f=((h=o[0])==null?void 0:h.getBoundingClientRect().top)??0;r.style.height=c-f+"px"})};function j({children:i=[],columns:r,style:d={}}){const t=b.useRef(null);return b.useLayoutEffect(()=>{if(!t.current)return;const e=Array.from(t.current.children);y(e,t.current,r)},[t,r]),b.useEffect(()=>{if(!t.current)return;const e={},o=t.current.style,u=()=>{Object.keys(r).forEach(s=>{const n=t.current,a=r[s],c=e[s];if(!n||!a)return;const f=Array.from(n.children),h=(100/a.columns).toFixed(3)+"%";(c!=null&&c.matches||!a.query)&&(o.setProperty("--cell-width",h),window.requestAnimationFrame(()=>y(f,n,r)))})};return Object.keys(r).forEach(s=>{const n=r[s];!n||!n.query||(e[s]=window.matchMedia(n.query),e[s].addEventListener("change",u))}),u(),()=>{Object.keys(e).forEach(s=>{var n;return(n=e[s])==null?void 0:n.removeEventListener("change",u)})}},[r,t]),b.useEffect(()=>{if(!t.current)return;const e=n=>{if(!t.current)return;const a=Array.from(t.current.children),c=n!=null&&n.length?n.map(f=>f.target):a;y(c,o,r)},o=t.current,u=new ResizeObserver(n=>{e(n)}),s=new MutationObserver(n=>{e(n)});return Array.from(t.current.children).forEach(n=>u.observe(n)),u.observe(o),s.observe(o,C),()=>{u.disconnect(),s.disconnect()}},[t,r]),l.jsx("div",{className:"mason-container",ref:t,style:d,children:b.Children.toArray(i).filter(e=>e).map((e,o)=>l.jsx("div",{children:e},`child-${o}`))})}return j}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-stone-mason",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Greg Archer",
|
|
6
6
|
"email": "greg.taff@gmail.com"
|
|
@@ -10,17 +10,24 @@
|
|
|
10
10
|
"url": "git+https://github.com/nihlton/mason"
|
|
11
11
|
},
|
|
12
12
|
"homepage": "https://github.com/nihlton/mason",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
13
16
|
"main": "./dist/react-stone-mason.umd.js",
|
|
14
|
-
"module": "./dist/react-stone-mason.
|
|
17
|
+
"module": "./dist/react-stone-mason.mjs",
|
|
15
18
|
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/react-stone-mason.mjs",
|
|
23
|
+
"require": "./dist/react-stone-mason.umd.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
16
26
|
"peerDependencies": {
|
|
17
27
|
"react": ">=16.8.6",
|
|
18
28
|
"react-dom": ">=16.8.6"
|
|
19
29
|
},
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"typescript": "^5.9.3",
|
|
22
|
-
"webpack": "^4.35.0"
|
|
23
|
-
},
|
|
30
|
+
"dependencies": {},
|
|
24
31
|
"scripts": {
|
|
25
32
|
"dev": "vite",
|
|
26
33
|
"build": "tsc && vite build",
|
|
@@ -40,6 +47,7 @@
|
|
|
40
47
|
"sass": "^1.95.1",
|
|
41
48
|
"source-map-loader": "^0.2.4",
|
|
42
49
|
"ts-loader": "^7.0.0",
|
|
50
|
+
"typescript": "^5.9.3",
|
|
43
51
|
"typescript-eslint": "^8.50.1",
|
|
44
52
|
"vite": "^6.4.1",
|
|
45
53
|
"vite-plugin-dts": "^4.5.4",
|
package/.babelrc
DELETED
package/build/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const react_stone_mason_1 = __importDefault(require("./react-stone-mason"));
|
|
7
|
-
exports.default = react_stone_mason_1.default;
|
|
8
|
-
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;AAAA,4EAAwC;AAIxC,kBAAe,2BAAK,CAAC"}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.default = Mason;
|
|
37
|
-
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
|
-
const React = __importStar(require("react"));
|
|
39
|
-
const util_1 = require("./util");
|
|
40
|
-
require("./react-stone-mason.css");
|
|
41
|
-
function Mason({ children = [], columns, style = {} }) {
|
|
42
|
-
const containerRef = React.useRef(null);
|
|
43
|
-
React.useLayoutEffect(() => {
|
|
44
|
-
if (!containerRef.current)
|
|
45
|
-
return;
|
|
46
|
-
const containerChildren = Array.from(containerRef.current.children);
|
|
47
|
-
(0, util_1.positionChildren)(containerChildren, containerRef.current, columns);
|
|
48
|
-
}, [containerRef, columns]);
|
|
49
|
-
React.useEffect(() => {
|
|
50
|
-
// Listen for mediaQuery matches, and set the number of columns.
|
|
51
|
-
if (!containerRef.current)
|
|
52
|
-
return;
|
|
53
|
-
const queryListeners = {};
|
|
54
|
-
const containerStyle = containerRef.current.style;
|
|
55
|
-
// handle media query match changes
|
|
56
|
-
const getQueryMatches = () => {
|
|
57
|
-
Object.keys(columns).forEach((thisPoint) => {
|
|
58
|
-
const container = containerRef.current;
|
|
59
|
-
const breakPointColumns = columns[thisPoint];
|
|
60
|
-
const queryListener = queryListeners[thisPoint];
|
|
61
|
-
if (!container || !breakPointColumns)
|
|
62
|
-
return;
|
|
63
|
-
const containerChildren = Array.from(container.children);
|
|
64
|
-
const cellWidth = (100 / breakPointColumns.columns).toFixed(3) + "%";
|
|
65
|
-
if ((queryListener === null || queryListener === void 0 ? void 0 : queryListener.matches) || !breakPointColumns.query) {
|
|
66
|
-
containerStyle.setProperty("--cell-width", cellWidth);
|
|
67
|
-
window.requestAnimationFrame(() => (0, util_1.positionChildren)(containerChildren, container, columns));
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
};
|
|
71
|
-
// listen for query matches, attach listener
|
|
72
|
-
Object.keys(columns).forEach((thisPoint) => {
|
|
73
|
-
const pointColumns = columns[thisPoint];
|
|
74
|
-
if (!pointColumns || !pointColumns.query)
|
|
75
|
-
return;
|
|
76
|
-
queryListeners[thisPoint] = window.matchMedia(pointColumns.query);
|
|
77
|
-
queryListeners[thisPoint].addEventListener("change", getQueryMatches);
|
|
78
|
-
});
|
|
79
|
-
getQueryMatches();
|
|
80
|
-
return () => {
|
|
81
|
-
// stop listening for query matches
|
|
82
|
-
Object.keys(queryListeners).forEach((breakPoint) => { var _a; return (_a = queryListeners[breakPoint]) === null || _a === void 0 ? void 0 : _a.removeEventListener("change", getQueryMatches); });
|
|
83
|
-
};
|
|
84
|
-
}, [columns, containerRef]);
|
|
85
|
-
React.useEffect(() => {
|
|
86
|
-
// listen for document resizing, and dom tree changes. recalculate transforms as needed.
|
|
87
|
-
if (!containerRef.current)
|
|
88
|
-
return;
|
|
89
|
-
const doPositionChildren = (entries) => {
|
|
90
|
-
if (!containerRef.current)
|
|
91
|
-
return;
|
|
92
|
-
const containerChildren = Array.from(containerRef.current.children);
|
|
93
|
-
const targets = (entries === null || entries === void 0 ? void 0 : entries.length) ? entries.map((entry) => entry.target) : containerChildren;
|
|
94
|
-
(0, util_1.positionChildren)(targets, containerNode, columns);
|
|
95
|
-
};
|
|
96
|
-
const containerNode = containerRef.current;
|
|
97
|
-
const sizeObserver = new ResizeObserver((entries) => {
|
|
98
|
-
doPositionChildren(entries);
|
|
99
|
-
});
|
|
100
|
-
const domObserver = new MutationObserver((entries) => {
|
|
101
|
-
doPositionChildren(entries);
|
|
102
|
-
});
|
|
103
|
-
Array.from(containerRef.current.children).forEach((child) => sizeObserver.observe(child));
|
|
104
|
-
sizeObserver.observe(containerNode);
|
|
105
|
-
domObserver.observe(containerNode, util_1.mutationConfig);
|
|
106
|
-
return () => {
|
|
107
|
-
sizeObserver.disconnect();
|
|
108
|
-
domObserver.disconnect();
|
|
109
|
-
};
|
|
110
|
-
}, [containerRef, columns]);
|
|
111
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: "mason-container", ref: containerRef, style: style, children: React.Children.toArray(children)
|
|
112
|
-
.filter((c) => c)
|
|
113
|
-
.map((child, i) => ((0, jsx_runtime_1.jsx)("div", { children: child }, `child-${i}`))) }));
|
|
114
|
-
}
|
|
115
|
-
//# sourceMappingURL=react-stone-mason.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react-stone-mason.js","sourceRoot":"","sources":["../src/react-stone-mason.tsx"],"names":[],"mappings":"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"}
|
package/build/types.js
DELETED
package/build/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/build/util.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.positionChildren = exports.mutationConfig = void 0;
|
|
4
|
-
exports.mutationConfig = { childList: true, subtree: true };
|
|
5
|
-
const getBreakPoint = (config) => {
|
|
6
|
-
const fallBack = Object.keys(config).find((thisBreakPoint) => { var _a; return !((_a = config[thisBreakPoint]) === null || _a === void 0 ? void 0 : _a.query); });
|
|
7
|
-
const matchingPoint = Object.keys(config).find((thisBreakPoint) => {
|
|
8
|
-
var _a;
|
|
9
|
-
const breakpointQuery = (_a = config[thisBreakPoint]) === null || _a === void 0 ? void 0 : _a.query;
|
|
10
|
-
return breakpointQuery && window.matchMedia(breakpointQuery).matches;
|
|
11
|
-
});
|
|
12
|
-
return matchingPoint || fallBack;
|
|
13
|
-
};
|
|
14
|
-
const positionChildren = (targets, container, columnConfig) => {
|
|
15
|
-
// iterate through children - by column. find gap under each child and the element in the row below it.
|
|
16
|
-
// add the gap to the 'column debt' and move the child vertically accordingly.
|
|
17
|
-
var _a;
|
|
18
|
-
const breakPoint = getBreakPoint(columnConfig);
|
|
19
|
-
if (!breakPoint || !container)
|
|
20
|
-
return;
|
|
21
|
-
const columns = +(((_a = columnConfig[breakPoint]) === null || _a === void 0 ? void 0 : _a.columns) || 1);
|
|
22
|
-
const children = Array.from(container.children);
|
|
23
|
-
// find the first row of items impacted by the reposition, and begin positioning south of there
|
|
24
|
-
const firstTarget = targets.reduce((a, c) => Math.min(a, children.indexOf(c)), children.length);
|
|
25
|
-
const firstTargetRow = Math.max(0, firstTarget - columns);
|
|
26
|
-
children.forEach((child, index) => {
|
|
27
|
-
if (index >= firstTargetRow) {
|
|
28
|
-
const column = index % columns;
|
|
29
|
-
const rowChildren = children.slice(index - column, index - column + columns);
|
|
30
|
-
const prevChild = children[index - columns];
|
|
31
|
-
const prevDebt = Number((prevChild === null || prevChild === void 0 ? void 0 : prevChild.getAttribute("data-debt")) || 0);
|
|
32
|
-
const maxHeight = Math.max(...rowChildren.map((rowChild) => rowChild.getBoundingClientRect().height));
|
|
33
|
-
const debt = prevDebt + Math.ceil(maxHeight - child.getBoundingClientRect().height);
|
|
34
|
-
child.setAttribute("data-debt", String(debt));
|
|
35
|
-
child.style.transform = index > columns - 1 ? `translateY(-${prevDebt}px)` : "";
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
window.requestAnimationFrame(() => {
|
|
39
|
-
var _a, _b;
|
|
40
|
-
const lastChildren = children.slice(-1 * columns);
|
|
41
|
-
const childBottomEdge = Math.max(...lastChildren.map((c) => c.getBoundingClientRect().bottom));
|
|
42
|
-
const childTopEdge = (_b = (_a = children[0]) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().top) !== null && _b !== void 0 ? _b : 0;
|
|
43
|
-
container.style.height = childBottomEdge - childTopEdge + "px";
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
exports.positionChildren = positionChildren;
|
|
47
|
-
//# sourceMappingURL=util.js.map
|
package/build/util.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/dev/App.css
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
body {
|
|
2
|
-
background: #eee;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
.App {
|
|
6
|
-
max-width: 60rem;
|
|
7
|
-
margin: auto;
|
|
8
|
-
padding: 5rem 1rem;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
h1,
|
|
12
|
-
h2 {
|
|
13
|
-
padding: 0.5rem;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.App img {
|
|
17
|
-
max-width: 100%;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.App .random-entry .entry-content {
|
|
21
|
-
margin: calc(1vw + 0.25rem);
|
|
22
|
-
background: white;
|
|
23
|
-
box-shadow:
|
|
24
|
-
0 0 0 1px #0003,
|
|
25
|
-
0 0.75rem 0.75rem -0.5rem #0004;
|
|
26
|
-
border-radius: 3px;
|
|
27
|
-
padding: 0.5rem;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.App .random-entry .entry-content p {
|
|
31
|
-
margin: 0.5rem 0;
|
|
32
|
-
font-size: 0.85rem;
|
|
33
|
-
}
|
package/dev/App.tsx
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import Mason from "../src/react-stone-mason";
|
|
2
|
-
import { columnConfig, columnConfigImages, randomColors, randomEntries, staticColumn } from "./util";
|
|
3
|
-
|
|
4
|
-
import "./App.css";
|
|
5
|
-
|
|
6
|
-
const App = () => {
|
|
7
|
-
return (
|
|
8
|
-
<div className="App">
|
|
9
|
-
<h1>Responsive</h1>
|
|
10
|
-
<h2>HTML children with gutter</h2>
|
|
11
|
-
<Mason columns={columnConfig}>{randomEntries.slice(0, 16)}</Mason>
|
|
12
|
-
|
|
13
|
-
<h2>Plain image children, no gutter</h2>
|
|
14
|
-
<Mason columns={columnConfigImages}>{randomColors.slice(0, 24)}</Mason>
|
|
15
|
-
|
|
16
|
-
<h1>Static</h1>
|
|
17
|
-
<Mason columns={staticColumn}>{randomEntries.slice(0, 16)}</Mason>
|
|
18
|
-
</div>
|
|
19
|
-
);
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export default App;
|
package/dev/main.tsx
DELETED
package/dev/util.tsx
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
const hipsum = `Taxidermy proident hoodie brooklyn PBR&B godard succulents actually. Vice exercitation banh mi kombucha sed squid. Aliqua mumblecore raw denim pitchfork, intelligentsia in blog tote bag glossier normcore vice sartorial narwhal dolore echo park. Irony heirloom do, subway tile XOXO gluten-free magna. Normcore pok pok seitan hella roof party iceland humblebrag disrupt lumbersexual flexitarian mumblecore fingerstache helvetica. Yr laboris iceland, wayfarers proident hell of kitsch tilde palo santo dreamcatcher cupidatat gastropub ea. Tbh sriracha crucifix jianbing semiotics typewriter in et migas tacos.`;
|
|
2
|
-
|
|
3
|
-
function toHex(n: number) {
|
|
4
|
-
var hex = n.toString(16);
|
|
5
|
-
while (hex.length < 2) {
|
|
6
|
-
hex = "0" + hex;
|
|
7
|
-
}
|
|
8
|
-
return hex;
|
|
9
|
-
}
|
|
10
|
-
const getRandomColor = () => {
|
|
11
|
-
const r = Math.round(Math.random() * 255);
|
|
12
|
-
const g = Math.round(Math.random() * 255);
|
|
13
|
-
const b = Math.round(Math.random() * 255);
|
|
14
|
-
return toHex(r) + toHex(g) + toHex(b);
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export const randomEntries = new Array(80).fill(".").map(() => {
|
|
18
|
-
const textStart = Math.round(Math.random() * 400);
|
|
19
|
-
const height = Math.round(Math.random() * 300) + 100;
|
|
20
|
-
const text = hipsum.slice(textStart, textStart + height / 5);
|
|
21
|
-
return (
|
|
22
|
-
<div className="random-entry">
|
|
23
|
-
<div className="entry-content">
|
|
24
|
-
<img src={`https://dummyimage.com/300x${height}/${getRandomColor()}.png&text=+`} alt="colors!" />
|
|
25
|
-
<p>{text}</p>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
export const randomColors = new Array(80).fill(".").map(() => {
|
|
32
|
-
const height = Math.round(Math.random() * 300) + 100;
|
|
33
|
-
return <img style={{ display: "block" }} src={`https://dummyimage.com/300x${height}/${getRandomColor()}.png&text=+`} alt="colors!" />;
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
export const columnConfig = {
|
|
37
|
-
small: {
|
|
38
|
-
query: "(max-width: 720px)",
|
|
39
|
-
columns: 2,
|
|
40
|
-
},
|
|
41
|
-
medium: {
|
|
42
|
-
query: "(min-width: calc(720px + 1px)) and (max-width: calc(1023px - 1px) )",
|
|
43
|
-
columns: 3,
|
|
44
|
-
},
|
|
45
|
-
large: {
|
|
46
|
-
query: "(min-width: 1023px)",
|
|
47
|
-
columns: 4,
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export const columnConfigImages = {
|
|
52
|
-
small: {
|
|
53
|
-
query: "(max-width: 720px)",
|
|
54
|
-
columns: 3,
|
|
55
|
-
},
|
|
56
|
-
medium: {
|
|
57
|
-
query: "(min-width: calc(720px + 1px)) and (max-width: calc(1023px - 1px) )",
|
|
58
|
-
columns: 4,
|
|
59
|
-
},
|
|
60
|
-
large: {
|
|
61
|
-
query: "(min-width: 1023px)",
|
|
62
|
-
columns: 5,
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export const staticColumn = {
|
|
67
|
-
default: {
|
|
68
|
-
columns: 3,
|
|
69
|
-
},
|
|
70
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";require('./index.css');const y=require("react/jsx-runtime"),v=require("react");function C(s){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const u in s)if(u!=="default"){const e=Object.getOwnPropertyDescriptor(s,u);Object.defineProperty(n,u,e.get?e:{enumerable:!0,get:()=>s[u]})}}return n.default=s,Object.freeze(n)}const m=C(v),j={childList:!0,subtree:!0},E=s=>{const n=Object.keys(s).find(e=>{var t;return!((t=s[e])!=null&&t.query)});return Object.keys(s).find(e=>{var c;const t=(c=s[e])==null?void 0:c.query;return t&&window.matchMedia(t).matches})||n},b=(s,n,u)=>{var r;const e=E(u);if(!e||!n)return;const t=+(((r=u[e])==null?void 0:r.columns)||1),c=Array.from(n.children),d=s.reduce((a,o)=>Math.min(a,c.indexOf(o)),c.length),i=Math.max(0,d-t);c.forEach((a,o)=>{if(o>=i){const l=o%t,h=c.slice(o-l,o-l+t),f=c[o-t],g=Number((f==null?void 0:f.getAttribute("data-debt"))||0),p=Math.max(...h.map(w=>w.getBoundingClientRect().height)),O=g+Math.ceil(p-a.getBoundingClientRect().height);a.setAttribute("data-debt",String(O)),a.style.transform=o>t-1?`translateY(-${g}px)`:""}}),window.requestAnimationFrame(()=>{var h;const a=c.slice(-1*t),o=Math.max(...a.map(f=>f.getBoundingClientRect().bottom)),l=((h=c[0])==null?void 0:h.getBoundingClientRect().top)??0;n.style.height=o-l+"px"})};function k({children:s=[],columns:n,style:u={}}){const e=m.useRef(null);return m.useLayoutEffect(()=>{if(!e.current)return;const t=Array.from(e.current.children);b(t,e.current,n)},[e,n]),m.useEffect(()=>{if(!e.current)return;const t={},c=e.current.style,d=()=>{Object.keys(n).forEach(i=>{const r=e.current,a=n[i],o=t[i];if(!r||!a)return;const l=Array.from(r.children),h=(100/a.columns).toFixed(3)+"%";(o!=null&&o.matches||!a.query)&&(c.setProperty("--cell-width",h),window.requestAnimationFrame(()=>b(l,r,n)))})};return Object.keys(n).forEach(i=>{const r=n[i];!r||!r.query||(t[i]=window.matchMedia(r.query),t[i].addEventListener("change",d))}),d(),()=>{Object.keys(t).forEach(i=>{var r;return(r=t[i])==null?void 0:r.removeEventListener("change",d)})}},[n,e]),m.useEffect(()=>{if(!e.current)return;const t=r=>{if(!e.current)return;const a=Array.from(e.current.children),o=r!=null&&r.length?r.map(l=>l.target):a;b(o,c,n)},c=e.current,d=new ResizeObserver(r=>{t(r)}),i=new MutationObserver(r=>{t(r)});return Array.from(e.current.children).forEach(r=>d.observe(r)),d.observe(c),i.observe(c,j),()=>{d.disconnect(),i.disconnect()}},[e,n]),y.jsx("div",{className:"mason-container",ref:e,style:u,children:m.Children.toArray(s).filter(t=>t).map((t,c)=>y.jsx("div",{children:t},`child-${c}`))})}module.exports=k;
|
package/index.html
DELETED
package/src/index.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
.mason-container {
|
|
2
|
-
position: relative;
|
|
3
|
-
overflow: hidden;
|
|
4
|
-
--cell-width: 100%;
|
|
5
|
-
box-sizing: border-box;
|
|
6
|
-
margin: 0;
|
|
7
|
-
padding: 0;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.mason-container > * {
|
|
11
|
-
box-sizing: inherit;
|
|
12
|
-
display: inline-block;
|
|
13
|
-
vertical-align: top;
|
|
14
|
-
width: var(--cell-width);
|
|
15
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
|
|
3
|
-
import { mutationConfig, positionChildren } from "./util";
|
|
4
|
-
import { entryWithTarget, MasonProps } from "./types";
|
|
5
|
-
|
|
6
|
-
import "./react-stone-mason.css";
|
|
7
|
-
|
|
8
|
-
export default function Mason({ children = [], columns, style = {} }: MasonProps) {
|
|
9
|
-
const containerRef = React.useRef<HTMLDivElement>(null);
|
|
10
|
-
|
|
11
|
-
React.useLayoutEffect(() => {
|
|
12
|
-
if (!containerRef.current) return;
|
|
13
|
-
const containerChildren = Array.from(containerRef.current.children) as HTMLElement[];
|
|
14
|
-
positionChildren(containerChildren, containerRef.current, columns);
|
|
15
|
-
}, [containerRef, columns]);
|
|
16
|
-
|
|
17
|
-
React.useEffect(() => {
|
|
18
|
-
// Listen for mediaQuery matches, and set the number of columns.
|
|
19
|
-
if (!containerRef.current) return;
|
|
20
|
-
|
|
21
|
-
const queryListeners: { [key: string]: MediaQueryList } = {};
|
|
22
|
-
const containerStyle = containerRef.current.style;
|
|
23
|
-
|
|
24
|
-
// handle media query match changes
|
|
25
|
-
const getQueryMatches = (): void => {
|
|
26
|
-
Object.keys(columns).forEach((thisPoint: string) => {
|
|
27
|
-
const container = containerRef.current;
|
|
28
|
-
const breakPointColumns = columns[thisPoint];
|
|
29
|
-
const queryListener = queryListeners[thisPoint];
|
|
30
|
-
|
|
31
|
-
if (!container || !breakPointColumns) return;
|
|
32
|
-
|
|
33
|
-
const containerChildren = Array.from(container.children) as HTMLElement[];
|
|
34
|
-
const cellWidth: string = (100 / breakPointColumns.columns).toFixed(3) + "%";
|
|
35
|
-
|
|
36
|
-
if (queryListener?.matches || !breakPointColumns.query) {
|
|
37
|
-
containerStyle.setProperty("--cell-width", cellWidth);
|
|
38
|
-
window.requestAnimationFrame(() => positionChildren(containerChildren, container, columns));
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// listen for query matches, attach listener
|
|
44
|
-
Object.keys(columns).forEach((thisPoint: string) => {
|
|
45
|
-
const pointColumns = columns[thisPoint];
|
|
46
|
-
if (!pointColumns || !pointColumns.query) return;
|
|
47
|
-
queryListeners[thisPoint] = window.matchMedia(pointColumns.query);
|
|
48
|
-
queryListeners[thisPoint].addEventListener("change", getQueryMatches);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
getQueryMatches();
|
|
52
|
-
|
|
53
|
-
return () => {
|
|
54
|
-
// stop listening for query matches
|
|
55
|
-
Object.keys(queryListeners).forEach((breakPoint) => queryListeners[breakPoint]?.removeEventListener("change", getQueryMatches));
|
|
56
|
-
};
|
|
57
|
-
}, [columns, containerRef]);
|
|
58
|
-
|
|
59
|
-
React.useEffect(() => {
|
|
60
|
-
// listen for document resizing, and dom tree changes. recalculate transforms as needed.
|
|
61
|
-
if (!containerRef.current) return;
|
|
62
|
-
|
|
63
|
-
const doPositionChildren = (entries: entryWithTarget[]): void => {
|
|
64
|
-
if (!containerRef.current) return;
|
|
65
|
-
|
|
66
|
-
const containerChildren = Array.from(containerRef.current.children) as HTMLElement[];
|
|
67
|
-
const targets = entries?.length ? (entries.map((entry) => entry.target) as HTMLElement[]) : containerChildren;
|
|
68
|
-
positionChildren(targets, containerNode, columns);
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const containerNode = containerRef.current as HTMLElement;
|
|
72
|
-
const sizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {
|
|
73
|
-
doPositionChildren(entries);
|
|
74
|
-
});
|
|
75
|
-
const domObserver = new MutationObserver((entries: MutationRecord[]) => {
|
|
76
|
-
doPositionChildren(entries);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
Array.from(containerRef.current.children).forEach((child) => sizeObserver.observe(child));
|
|
80
|
-
sizeObserver.observe(containerNode);
|
|
81
|
-
domObserver.observe(containerNode, mutationConfig);
|
|
82
|
-
|
|
83
|
-
return () => {
|
|
84
|
-
sizeObserver.disconnect();
|
|
85
|
-
domObserver.disconnect();
|
|
86
|
-
};
|
|
87
|
-
}, [containerRef, columns]);
|
|
88
|
-
|
|
89
|
-
return (
|
|
90
|
-
<div className={"mason-container"} ref={containerRef} style={style}>
|
|
91
|
-
{React.Children.toArray(children)
|
|
92
|
-
.filter((c) => c)
|
|
93
|
-
.map((child: React.ReactNode, i: number) => (
|
|
94
|
-
<div key={`child-${i}`}>{child}</div>
|
|
95
|
-
))}
|
|
96
|
-
</div>
|
|
97
|
-
);
|
|
98
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export interface MutationConfiguration {
|
|
2
|
-
childList: boolean;
|
|
3
|
-
subtree: boolean;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface BreakPointData {
|
|
7
|
-
query?: string;
|
|
8
|
-
columns: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface MasonryConfig {
|
|
12
|
-
[key: string]: BreakPointData;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface MasonProps {
|
|
16
|
-
children?: React.ReactNode[] | undefined;
|
|
17
|
-
columns: MasonryConfig;
|
|
18
|
-
style?: React.CSSProperties;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export type entryWithTarget = {
|
|
22
|
-
target: Node;
|
|
23
|
-
};
|
package/src/util.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { MasonryConfig, MutationConfiguration } from "./types";
|
|
2
|
-
|
|
3
|
-
export const mutationConfig = { childList: true, subtree: true } as MutationConfiguration;
|
|
4
|
-
|
|
5
|
-
const getBreakPoint = (config: MasonryConfig) => {
|
|
6
|
-
const fallBack = Object.keys(config).find((thisBreakPoint) => !config[thisBreakPoint]?.query);
|
|
7
|
-
const matchingPoint = Object.keys(config).find((thisBreakPoint) => {
|
|
8
|
-
const breakpointQuery = config[thisBreakPoint]?.query;
|
|
9
|
-
return breakpointQuery && window.matchMedia(breakpointQuery).matches;
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
return matchingPoint || fallBack;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const positionChildren = (targets: HTMLElement[], container: HTMLElement, columnConfig: MasonryConfig): void => {
|
|
16
|
-
// iterate through children - by column. find gap under each child and the element in the row below it.
|
|
17
|
-
// add the gap to the 'column debt' and move the child vertically accordingly.
|
|
18
|
-
|
|
19
|
-
const breakPoint = getBreakPoint(columnConfig);
|
|
20
|
-
|
|
21
|
-
if (!breakPoint || !container) return;
|
|
22
|
-
|
|
23
|
-
const columns: number = +(columnConfig[breakPoint]?.columns || 1);
|
|
24
|
-
const children: HTMLElement[] = Array.from(container.children) as HTMLElement[];
|
|
25
|
-
|
|
26
|
-
// find the first row of items impacted by the reposition, and begin positioning south of there
|
|
27
|
-
const firstTarget = targets.reduce((a, c) => Math.min(a, children.indexOf(c)), children.length);
|
|
28
|
-
const firstTargetRow = Math.max(0, firstTarget - columns);
|
|
29
|
-
|
|
30
|
-
children.forEach((child: HTMLElement, index: number) => {
|
|
31
|
-
if (index >= firstTargetRow) {
|
|
32
|
-
const column: number = index % columns;
|
|
33
|
-
const rowChildren: HTMLElement[] = children.slice(index - column, index - column + columns);
|
|
34
|
-
|
|
35
|
-
const prevChild = children[index - columns];
|
|
36
|
-
const prevDebt = Number(prevChild?.getAttribute("data-debt") || 0);
|
|
37
|
-
|
|
38
|
-
const maxHeight: number = Math.max(...rowChildren.map((rowChild: HTMLElement) => rowChild.getBoundingClientRect().height));
|
|
39
|
-
const debt: number = prevDebt + Math.ceil(maxHeight - child.getBoundingClientRect().height);
|
|
40
|
-
|
|
41
|
-
child.setAttribute("data-debt", String(debt));
|
|
42
|
-
child.style.transform = index > columns - 1 ? `translateY(-${prevDebt}px)` : "";
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
window.requestAnimationFrame(() => {
|
|
47
|
-
const lastChildren = children.slice(-1 * columns);
|
|
48
|
-
const childBottomEdge = Math.max(...lastChildren.map((c: HTMLElement) => c.getBoundingClientRect().bottom));
|
|
49
|
-
const childTopEdge = children[0]?.getBoundingClientRect().top ?? 0;
|
|
50
|
-
container.style.height = childBottomEdge - childTopEdge + "px";
|
|
51
|
-
});
|
|
52
|
-
};
|
package/tsconfig.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"strict": true,
|
|
4
|
-
"esModuleInterop": true,
|
|
5
|
-
"outDir": "./build/",
|
|
6
|
-
"sourceMap": true,
|
|
7
|
-
"noImplicitAny": true,
|
|
8
|
-
"module": "commonjs",
|
|
9
|
-
"target": "es6",
|
|
10
|
-
"jsx": "react-jsx",
|
|
11
|
-
"types": ["node"]
|
|
12
|
-
},
|
|
13
|
-
"include": ["src/**/*"]
|
|
14
|
-
}
|
package/vite.config.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vite";
|
|
2
|
-
import react from "@vitejs/plugin-react";
|
|
3
|
-
import dts from "vite-plugin-dts";
|
|
4
|
-
import { libInjectCss } from "vite-plugin-lib-inject-css";
|
|
5
|
-
import { resolve } from "path";
|
|
6
|
-
|
|
7
|
-
export default defineConfig({
|
|
8
|
-
plugins: [react(), libInjectCss(), dts({ insertTypesEntry: true })],
|
|
9
|
-
build: {
|
|
10
|
-
lib: {
|
|
11
|
-
// Could also be a dictionary or array of multiple entry points
|
|
12
|
-
entry: resolve(__dirname, "src/index.ts"),
|
|
13
|
-
name: "react-stone-mason",
|
|
14
|
-
fileName: (format) => `react-stone-mason.${format}.js`,
|
|
15
|
-
formats: ["es", "cjs"],
|
|
16
|
-
},
|
|
17
|
-
rollupOptions: {
|
|
18
|
-
// Externalize deps that shouldn't be bundled into your library
|
|
19
|
-
external: ["react", "react-dom", "react/jsx-runtime"],
|
|
20
|
-
output: {
|
|
21
|
-
globals: {
|
|
22
|
-
react: "React",
|
|
23
|
-
"react-dom": "ReactDOM",
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
});
|
package/webpack.config.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
mode: 'production',
|
|
5
|
-
entry: './src/index.tsx',
|
|
6
|
-
output: {
|
|
7
|
-
path: path.resolve(__dirname, 'build'),
|
|
8
|
-
filename: '../build/index.js',
|
|
9
|
-
libraryTarget: 'commonjs2'
|
|
10
|
-
},
|
|
11
|
-
devtool: 'source-map',
|
|
12
|
-
resolve: {
|
|
13
|
-
// Add '.ts' and '.tsx' as resolvable extensions.
|
|
14
|
-
extensions: ['.webpack.js', '.web.js', '.ts', '.tsx', '.js'],
|
|
15
|
-
},
|
|
16
|
-
module: {
|
|
17
|
-
rules: [
|
|
18
|
-
{
|
|
19
|
-
test: /\.ts(x?)$/,
|
|
20
|
-
exclude: /node_modules/,
|
|
21
|
-
use: [
|
|
22
|
-
{
|
|
23
|
-
loader: "ts-loader"
|
|
24
|
-
}
|
|
25
|
-
]
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
enforce: "pre",
|
|
29
|
-
test: /\.js$/,
|
|
30
|
-
loader: "source-map-loader"
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
test: /\.js$/,
|
|
34
|
-
include: path.resolve(__dirname, 'src'),
|
|
35
|
-
exclude: /(node_modules|bower_components|build)/,
|
|
36
|
-
use: {
|
|
37
|
-
loader: 'babel-loader',
|
|
38
|
-
options: {
|
|
39
|
-
presets: ["@babel/env"],
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
test: /\.css$/i,
|
|
45
|
-
use: ['style-loader', 'css-loader'],
|
|
46
|
-
},
|
|
47
|
-
]
|
|
48
|
-
},
|
|
49
|
-
externals: {
|
|
50
|
-
'react': 'commonjs react',
|
|
51
|
-
"react-dom": "ReactDOM"
|
|
52
|
-
}
|
|
53
|
-
};
|
|
File without changes
|