@full-ui/headless-grid 7.0.0-beta.6 → 7.0.0-beta.7
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/package.json +5 -9
- package/cjs/index.cjs +0 -371
- /package/{esm/index.d.ts → index.d.ts} +0 -0
- /package/{esm/index.js → index.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@full-ui/headless-grid",
|
|
3
|
-
"version": "7.0.0-beta.
|
|
3
|
+
"version": "7.0.0-beta.7",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"headless",
|
|
6
6
|
"grid",
|
|
@@ -23,17 +23,13 @@
|
|
|
23
23
|
"url": "http://arshaw.com/"
|
|
24
24
|
},
|
|
25
25
|
"copyright": "2025 Adam Shaw",
|
|
26
|
-
"types": "./
|
|
27
|
-
"
|
|
28
|
-
"main": "./cjs/index.cjs",
|
|
26
|
+
"types": "./index.d.ts",
|
|
27
|
+
"main": "./index.js",
|
|
29
28
|
"exports": {
|
|
30
29
|
"./package.json": "./package.json",
|
|
31
30
|
".": {
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
"default": "./esm/index.js"
|
|
35
|
-
},
|
|
36
|
-
"require": "./cjs/index.cjs"
|
|
31
|
+
"types": "./index.d.ts",
|
|
32
|
+
"default": "./index.js"
|
|
37
33
|
}
|
|
38
34
|
},
|
|
39
35
|
"sideEffects": false
|
package/cjs/index.cjs
DELETED
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
function fracToCssDim(frac) {
|
|
6
|
-
return frac * 100 + '%';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function parseDimConfig(input, minDim = 0) {
|
|
10
|
-
if (input != null) {
|
|
11
|
-
if (typeof input === 'string') {
|
|
12
|
-
let m = input.match(/^(.*)(%|px)$/);
|
|
13
|
-
if (m) {
|
|
14
|
-
const num = parseFloat(m[1]);
|
|
15
|
-
if (!isNaN(num)) {
|
|
16
|
-
if (m[2] === '%') {
|
|
17
|
-
return { pixels: 0, frac: num / 100, min: minDim };
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
return { pixels: num, frac: 0, min: minDim };
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
else if (typeof input === 'number' && !isNaN(input)) {
|
|
26
|
-
return { pixels: input, frac: 0, min: minDim };
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function parseSiblingDimConfig(input, grow, // TODO: use (and sanitize)
|
|
31
|
-
minDim) {
|
|
32
|
-
const partialDimConfig = parseDimConfig(input, minDim);
|
|
33
|
-
return partialDimConfig
|
|
34
|
-
? Object.assign(Object.assign({}, partialDimConfig), { grow: grow || 0 }) : { pixels: 0, frac: 0, grow: grow || 1, min: minDim };
|
|
35
|
-
}
|
|
36
|
-
/*
|
|
37
|
-
Ensure at least one column can grow
|
|
38
|
-
Mutates in-place
|
|
39
|
-
*/
|
|
40
|
-
function ensureDimConfigsGrow(dimConfigs) {
|
|
41
|
-
for (const dimConfig of dimConfigs) {
|
|
42
|
-
if (dimConfig.grow) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
// make all expand equally
|
|
47
|
-
for (const dimConfig of dimConfigs) {
|
|
48
|
-
dimConfig.grow = 1;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function pixelizeDimConfigs(dimConfigs, clientDim) {
|
|
52
|
-
const pixelDims = [];
|
|
53
|
-
let preGrowTotal = 0;
|
|
54
|
-
let growDenom = 0;
|
|
55
|
-
for (const dimConfig of dimConfigs) {
|
|
56
|
-
const constrainedPixels = Math.max(dimConfig.pixels + (dimConfig.frac * clientDim), dimConfig.min);
|
|
57
|
-
pixelDims.push(constrainedPixels);
|
|
58
|
-
preGrowTotal += constrainedPixels;
|
|
59
|
-
growDenom += dimConfig.grow;
|
|
60
|
-
}
|
|
61
|
-
if (preGrowTotal < clientDim) {
|
|
62
|
-
const remainder = clientDim - preGrowTotal;
|
|
63
|
-
for (let i = 0; i < dimConfigs.length; i++) {
|
|
64
|
-
pixelDims[i] += remainder * (dimConfigs[i].grow / growDenom);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return [pixelDims, preGrowTotal];
|
|
68
|
-
}
|
|
69
|
-
function flexifyDimConfigs(dimConfigs, pixelDims) {
|
|
70
|
-
const flexDims = [];
|
|
71
|
-
const flexGrows = [];
|
|
72
|
-
let pixelTotal = 0;
|
|
73
|
-
let fracTotal = 0;
|
|
74
|
-
for (let i = 0; i < dimConfigs.length; i++) {
|
|
75
|
-
const dimConfig = dimConfigs[i];
|
|
76
|
-
const constrainedPixels = Math.max(dimConfig.pixels, dimConfig.min);
|
|
77
|
-
flexDims.push(constrainedPixels);
|
|
78
|
-
flexGrows.push(pixelDims[i] - constrainedPixels); // a pixel value, but used as a proportion
|
|
79
|
-
pixelTotal += dimConfig.pixels + (dimConfig.grow ? dimConfig.min : 0);
|
|
80
|
-
fracTotal += dimConfig.frac; // not possible to enforce min for percentage here
|
|
81
|
-
}
|
|
82
|
-
const minCanvasDim = serializeDimConfig({
|
|
83
|
-
pixels: pixelTotal,
|
|
84
|
-
frac: fracTotal,
|
|
85
|
-
});
|
|
86
|
-
return [flexDims, flexGrows, minCanvasDim];
|
|
87
|
-
}
|
|
88
|
-
function serializeDimConfig({ pixels, frac }) {
|
|
89
|
-
if (!frac) {
|
|
90
|
-
return pixels;
|
|
91
|
-
}
|
|
92
|
-
if (!pixels) {
|
|
93
|
-
return fracToCssDim(frac);
|
|
94
|
-
}
|
|
95
|
-
return `calc(${fracToCssDim(frac)} + ${pixels}px)`;
|
|
96
|
-
}
|
|
97
|
-
function resizeSiblingDimConfig(dimConfigs, pixelDims, clientDim, resizeIndex, resizeDim) {
|
|
98
|
-
const newDimConfigs = [];
|
|
99
|
-
for (let i = 0; i < resizeIndex; i++) {
|
|
100
|
-
newDimConfigs.push(resizeDimConfig(dimConfigs[i], pixelDims[i], clientDim));
|
|
101
|
-
}
|
|
102
|
-
newDimConfigs.push(resizeDimConfig(dimConfigs[resizeIndex], resizeDim, clientDim));
|
|
103
|
-
const len = dimConfigs.length;
|
|
104
|
-
let anyGrow = false;
|
|
105
|
-
for (let i = resizeIndex + 1; i < len; i++) {
|
|
106
|
-
const dimConfig = dimConfigs[i];
|
|
107
|
-
newDimConfigs.push(dimConfig);
|
|
108
|
-
if (dimConfig.grow) {
|
|
109
|
-
anyGrow = true;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (!anyGrow) {
|
|
113
|
-
for (let i = resizeIndex + 1; i < len; i++) {
|
|
114
|
-
newDimConfigs[i] = Object.assign({}, newDimConfigs[i], { grow: 1 });
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
return newDimConfigs;
|
|
118
|
-
}
|
|
119
|
-
function resizeDimConfig(dimConfig, newPixels, clientDim) {
|
|
120
|
-
const { min } = dimConfig;
|
|
121
|
-
newPixels = Math.max(min, newPixels);
|
|
122
|
-
if (dimConfig.pixels) {
|
|
123
|
-
return { pixels: newPixels, frac: 0, grow: 0, min };
|
|
124
|
-
}
|
|
125
|
-
return { pixels: 0, frac: newPixels / clientDim, grow: 0, min };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const ROW_BORDER_WIDTH = 1;
|
|
129
|
-
// Resource/Group Verticals
|
|
130
|
-
// -------------------------------------------------------------------------------------------------
|
|
131
|
-
function computeHeights(siblingNodes, getEntityKey, getEntityHeight, minHeight) {
|
|
132
|
-
const heightMap = new Map();
|
|
133
|
-
let [totalHeight, expandableCount] = computeTightHeights(siblingNodes, getEntityKey, getEntityHeight, heightMap);
|
|
134
|
-
if (minHeight != null && minHeight > totalHeight) {
|
|
135
|
-
expandHeights(siblingNodes, getEntityKey, heightMap, (minHeight - totalHeight) / expandableCount);
|
|
136
|
-
totalHeight = minHeight;
|
|
137
|
-
}
|
|
138
|
-
return [heightMap, totalHeight];
|
|
139
|
-
}
|
|
140
|
-
function computeTightHeights(siblingNodes, getEntityKey, getEntityHeight, heightMap) {
|
|
141
|
-
let totalHeight = 0;
|
|
142
|
-
let expandableCount = 0;
|
|
143
|
-
for (const siblingNode of siblingNodes) {
|
|
144
|
-
const entityKey = getEntityKey(siblingNode.entity);
|
|
145
|
-
let ownHeight = getEntityHeight(entityKey) || 0;
|
|
146
|
-
const [childrenHeight, childrenExpandableCount] = computeTightHeights(siblingNode.children, getEntityKey, getEntityHeight, heightMap);
|
|
147
|
-
if (siblingNode.pooledHeight) { // 'own' is side-by-side with children
|
|
148
|
-
if (ownHeight > childrenHeight) {
|
|
149
|
-
// children are smaller. grow them
|
|
150
|
-
expandHeights(siblingNode.children, getEntityKey, heightMap, (ownHeight - childrenHeight) / childrenExpandableCount);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
// own-element is smaller. grow to height of children
|
|
154
|
-
ownHeight = childrenHeight;
|
|
155
|
-
}
|
|
156
|
-
totalHeight += ownHeight;
|
|
157
|
-
}
|
|
158
|
-
else { // 'own' is above children
|
|
159
|
-
totalHeight += ownHeight + ROW_BORDER_WIDTH + childrenHeight;
|
|
160
|
-
}
|
|
161
|
-
heightMap.set(entityKey, ownHeight);
|
|
162
|
-
// expandable?
|
|
163
|
-
// vertically stacked, and not a group
|
|
164
|
-
if (siblingNode.pooledHeight === undefined) {
|
|
165
|
-
expandableCount++;
|
|
166
|
-
}
|
|
167
|
-
expandableCount += childrenExpandableCount;
|
|
168
|
-
}
|
|
169
|
-
return [
|
|
170
|
-
totalHeight + ROW_BORDER_WIDTH * (siblingNodes.length - 1),
|
|
171
|
-
expandableCount,
|
|
172
|
-
];
|
|
173
|
-
}
|
|
174
|
-
function expandHeights(siblingNodes, getEntityKey, heightMap, expansion) {
|
|
175
|
-
for (const siblingNode of siblingNodes) {
|
|
176
|
-
// expandable?
|
|
177
|
-
// vertically stacked, and not a group
|
|
178
|
-
if (siblingNode.pooledHeight === undefined) {
|
|
179
|
-
const entityKey = getEntityKey(siblingNode.entity);
|
|
180
|
-
heightMap.set(entityKey, heightMap.get(entityKey) + expansion);
|
|
181
|
-
}
|
|
182
|
-
expandHeights(siblingNode.children, getEntityKey, heightMap, expansion);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
function computeTopsFromHeights(siblingNodes, getEntityKey, heightMap) {
|
|
186
|
-
const topMap = new Map();
|
|
187
|
-
computeTopsStartingAt(siblingNodes, getEntityKey, heightMap, topMap, 0);
|
|
188
|
-
return topMap;
|
|
189
|
-
}
|
|
190
|
-
function computeTopsStartingAt(siblingNodes, getEntityKey, heightMap, topMap, top) {
|
|
191
|
-
for (let i = 0; i < siblingNodes.length; i++) {
|
|
192
|
-
const siblingNode = siblingNodes[i];
|
|
193
|
-
const entityKey = getEntityKey(siblingNode.entity);
|
|
194
|
-
topMap.set(entityKey, top);
|
|
195
|
-
if (!siblingNode.pooledHeight) {
|
|
196
|
-
top += heightMap.get(entityKey) + ROW_BORDER_WIDTH;
|
|
197
|
-
}
|
|
198
|
-
top = computeTopsStartingAt(siblingNode.children, getEntityKey, heightMap, topMap, top);
|
|
199
|
-
}
|
|
200
|
-
return top;
|
|
201
|
-
}
|
|
202
|
-
function findEntityByCoord(siblingNodes, entityTops, // keyed by createEntityId
|
|
203
|
-
entityHeights, // keyed by createEntityId
|
|
204
|
-
coord, // assumed >= 0
|
|
205
|
-
createEntityId) {
|
|
206
|
-
for (const siblingNode of siblingNodes) {
|
|
207
|
-
const entityKey = createEntityId(siblingNode.entity);
|
|
208
|
-
const siblingOwnTop = entityTops.get(entityKey);
|
|
209
|
-
const siblingOwnHeight = entityHeights.get(entityKey);
|
|
210
|
-
// intersection of the sibling's own element?
|
|
211
|
-
if (siblingOwnTop + siblingOwnHeight > coord) {
|
|
212
|
-
if (siblingNode.pooledHeight) {
|
|
213
|
-
// need more specific result
|
|
214
|
-
return findEntityByCoord(siblingNode.children, entityTops, entityHeights, coord, createEntityId);
|
|
215
|
-
}
|
|
216
|
-
else {
|
|
217
|
-
return [siblingNode.entity, siblingOwnTop, siblingOwnHeight];
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
else if (!siblingNode.pooledHeight) {
|
|
221
|
-
// search siblings below
|
|
222
|
-
const childrenRes = findEntityByCoord(siblingNode.children, entityTops, entityHeights, coord, createEntityId);
|
|
223
|
-
if (childrenRes) {
|
|
224
|
-
return childrenRes;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
class ScrollerSyncer {
|
|
231
|
-
constructor(isHorizontal = false) {
|
|
232
|
-
this.isHorizontal = isHorizontal;
|
|
233
|
-
this.scrollers = [];
|
|
234
|
-
this.destroyFuncs = [];
|
|
235
|
-
this.isPaused = false;
|
|
236
|
-
}
|
|
237
|
-
handleChildren(scrollers) {
|
|
238
|
-
if (!isArraysEqual(this.scrollers, scrollers)) {
|
|
239
|
-
this.destroy();
|
|
240
|
-
for (const scroller of scrollers) {
|
|
241
|
-
if (scroller) { // could be null
|
|
242
|
-
this.destroyFuncs.push(this.bindScroller(scroller));
|
|
243
|
-
this.scrollers.push(scroller);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
destroy() {
|
|
249
|
-
for (let destroyFunc of this.destroyFuncs) {
|
|
250
|
-
destroyFunc();
|
|
251
|
-
}
|
|
252
|
-
this.destroyFuncs = [];
|
|
253
|
-
this.scrollers = [];
|
|
254
|
-
}
|
|
255
|
-
get x() {
|
|
256
|
-
const { scrollers, masterScroller } = this;
|
|
257
|
-
return (masterScroller || scrollers[0]).x;
|
|
258
|
-
}
|
|
259
|
-
get y() {
|
|
260
|
-
const { scrollers, masterScroller } = this;
|
|
261
|
-
return (masterScroller || scrollers[0]).y;
|
|
262
|
-
}
|
|
263
|
-
scrollTo(scrollArg) {
|
|
264
|
-
this.isPaused = true;
|
|
265
|
-
const { scrollers } = this;
|
|
266
|
-
for (let scroller of scrollers) {
|
|
267
|
-
scroller.scrollTo(scrollArg);
|
|
268
|
-
}
|
|
269
|
-
this.isPaused = false;
|
|
270
|
-
}
|
|
271
|
-
addScrollEndListener(handler) {
|
|
272
|
-
var _a;
|
|
273
|
-
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.on('scrollEnd', handler);
|
|
274
|
-
}
|
|
275
|
-
removeScrollEndListener(handler) {
|
|
276
|
-
var _a;
|
|
277
|
-
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.off('scrollEnd', handler);
|
|
278
|
-
}
|
|
279
|
-
bindScroller(scroller) {
|
|
280
|
-
var _a, _b;
|
|
281
|
-
let { isHorizontal } = this;
|
|
282
|
-
const onScroll = (isUser) => {
|
|
283
|
-
if (!this.isPaused) {
|
|
284
|
-
if (!this.masterScroller || (this.masterScroller !== scroller && isUser)) {
|
|
285
|
-
this.assignMaster(scroller);
|
|
286
|
-
}
|
|
287
|
-
if (this.masterScroller === scroller) { // dealing with current
|
|
288
|
-
for (let otherScroller of this.scrollers) {
|
|
289
|
-
if (otherScroller !== scroller) {
|
|
290
|
-
if (isHorizontal) {
|
|
291
|
-
// TODO: user raw scrollLeft for better performance. No normalization necessary
|
|
292
|
-
otherScroller.scrollTo({ x: scroller.x });
|
|
293
|
-
}
|
|
294
|
-
else {
|
|
295
|
-
otherScroller.scrollTo({ y: scroller.y });
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
const onScrollEnd = (isUser) => {
|
|
303
|
-
var _a;
|
|
304
|
-
if (this.masterScroller === scroller) {
|
|
305
|
-
this.masterScroller = null;
|
|
306
|
-
const { x, y } = this; // new values
|
|
307
|
-
let isMoved = false;
|
|
308
|
-
if (this.isHorizontal) {
|
|
309
|
-
if (x !== this.prevX) {
|
|
310
|
-
this.prevX = x;
|
|
311
|
-
isMoved = true;
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
if (y !== this.prevY) {
|
|
316
|
-
this.prevY = y;
|
|
317
|
-
isMoved = true;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
if (isMoved) {
|
|
321
|
-
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.trigger('scrollEnd', isUser);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
};
|
|
325
|
-
(_a = scroller.listener.emitter) === null || _a === void 0 ? void 0 : _a.on('scroll', onScroll);
|
|
326
|
-
(_b = scroller.listener.emitter) === null || _b === void 0 ? void 0 : _b.on('scrollEnd', onScrollEnd);
|
|
327
|
-
return () => {
|
|
328
|
-
var _a, _b;
|
|
329
|
-
(_a = scroller.listener.emitter) === null || _a === void 0 ? void 0 : _a.off('scroll', onScroll);
|
|
330
|
-
(_b = scroller.listener.emitter) === null || _b === void 0 ? void 0 : _b.off('scrollEnd', onScrollEnd);
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
|
-
assignMaster(masterScroller) {
|
|
334
|
-
this.masterScroller = masterScroller;
|
|
335
|
-
for (let scroller of this.scrollers) {
|
|
336
|
-
if (scroller !== masterScroller) {
|
|
337
|
-
scroller.endScroll(); // to prevent residual scrolls from reclaiming master
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
function isArraysEqual(array0, array1) {
|
|
343
|
-
if (array0 === array1) {
|
|
344
|
-
return true;
|
|
345
|
-
}
|
|
346
|
-
let len = array0.length;
|
|
347
|
-
let i;
|
|
348
|
-
if (len !== array1.length) { // not array? or not same length?
|
|
349
|
-
return false;
|
|
350
|
-
}
|
|
351
|
-
for (i = 0; i < len; i += 1) {
|
|
352
|
-
if (array0[i] === array1[i]) {
|
|
353
|
-
return false;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
exports.ROW_BORDER_WIDTH = ROW_BORDER_WIDTH;
|
|
360
|
-
exports.ScrollerSyncer = ScrollerSyncer;
|
|
361
|
-
exports.computeHeights = computeHeights;
|
|
362
|
-
exports.computeTopsFromHeights = computeTopsFromHeights;
|
|
363
|
-
exports.ensureDimConfigsGrow = ensureDimConfigsGrow;
|
|
364
|
-
exports.findEntityByCoord = findEntityByCoord;
|
|
365
|
-
exports.flexifyDimConfigs = flexifyDimConfigs;
|
|
366
|
-
exports.parseDimConfig = parseDimConfig;
|
|
367
|
-
exports.parseSiblingDimConfig = parseSiblingDimConfig;
|
|
368
|
-
exports.pixelizeDimConfigs = pixelizeDimConfigs;
|
|
369
|
-
exports.resizeDimConfig = resizeDimConfig;
|
|
370
|
-
exports.resizeSiblingDimConfig = resizeSiblingDimConfig;
|
|
371
|
-
exports.serializeDimConfig = serializeDimConfig;
|
|
File without changes
|
|
File without changes
|