@dxos/lit-grid 0.6.10-main.3cfcc89 → 0.6.10-main.bbdfaa4

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.
@@ -2,6 +2,26 @@
2
2
  import { LitElement, html } from "lit";
3
3
  import { customElement, state, property } from "lit/decorators.js";
4
4
  import { ref, createRef } from "lit/directives/ref.js";
5
+
6
+ // packages/ui/lit-grid/src/position.ts
7
+ var colToA1Notation = (column) => {
8
+ return (column >= 26 ? String.fromCharCode("A".charCodeAt(0) + Math.floor(column / 26) - 1) : "") + String.fromCharCode("A".charCodeAt(0) + column % 26);
9
+ };
10
+ var rowToA1Notation = (row) => {
11
+ return `${row + 1}`;
12
+ };
13
+ var posFromNumericNotation = (notation) => {
14
+ const [iStr, jStr] = notation.split(",");
15
+ if (!iStr || !jStr) {
16
+ throw Error("[posFromNumericNotation] Bad input");
17
+ }
18
+ return {
19
+ i: parseInt(iStr),
20
+ j: parseInt(jStr)
21
+ };
22
+ };
23
+
24
+ // packages/ui/lit-grid/src/dx-grid.ts
5
25
  function _ts_decorate(decorators, target, key, desc) {
6
26
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
7
27
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
@@ -12,241 +32,129 @@ function _ts_decorate(decorators, target, key, desc) {
12
32
  r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
13
33
  return c > 3 && r && Object.defineProperty(target, key, r), r;
14
34
  }
15
- var gap = 1;
16
- var resizeTolerance = 8;
17
- var overscanCol = 1;
18
- var overscanRow = 1;
19
- var sizeColMin = 32;
20
- var sizeColMax = 1024;
21
- var sizeRowMin = 16;
22
- var sizeRowMax = 1024;
23
- var separator = ",";
24
- var colToA1Notation = (col) => {
25
- return (col >= 26 ? String.fromCharCode("A".charCodeAt(0) + Math.floor(col / 26) - 1) : "") + String.fromCharCode("A".charCodeAt(0) + col % 26);
26
- };
27
- var rowToA1Notation = (row) => {
28
- return `${row + 1}`;
29
- };
30
- var localChId = (c0) => `ch--${c0}`;
31
- var localRhId = (r0) => `rh--${r0}`;
32
- var getPage = (axis, event) => axis === "col" ? event.pageX : event.pageY;
35
+ var colSize = 64;
36
+ var rowSize = 20;
37
+ var gap = 0;
33
38
  var DxGrid = class extends LitElement {
34
39
  constructor() {
35
40
  super(...arguments);
36
- this.rowDefault = {
37
- size: 32
38
- };
39
- this.columnDefault = {
40
- size: 180
41
- };
42
- this.rows = {};
43
- this.columns = {};
44
- this.cells = {};
45
- //
46
- // `pos`, short for ‘position’, is the position in pixels of the viewport from the origin.
47
- //
41
+ this.values = {};
48
42
  this.posInline = 0;
49
43
  this.posBlock = 0;
50
- //
51
- // `size` (when not suffixed with ‘row’ or ‘col’, see above) is the size in pixels of the viewport.
52
- //
53
44
  this.sizeInline = 0;
54
45
  this.sizeBlock = 0;
55
- //
56
- // `overscan` is the amount in pixels to offset the grid content due to the number of overscanned columns or rows.
57
- //
58
- this.overscanInline = 0;
59
- this.overscanBlock = 0;
60
- //
61
- // `bin`, not short for anything, is the range in pixels within which virtualization does not need to reassess.
62
- //
63
- this.binInlineMin = 0;
64
- this.binInlineMax = this.colSize(0);
65
- this.binBlockMin = 0;
66
- this.binBlockMax = this.rowSize(0);
67
- //
68
- // `vis`, short for ‘visible’, is the range in numeric index of the columns or rows which should be rendered within
69
- // the viewport. These start with naïve values that are updated before first contentful render.
70
- //
71
- this.visColMin = 0;
72
- this.visColMax = 1;
73
- this.visRowMin = 0;
74
- this.visRowMax = 1;
75
- //
76
- // `template` is the rendered value of `grid-{axis}-template`.
77
- //
78
- this.templateColumns = `${this.colSize(0)}px`;
79
- this.templateRows = `${this.rowSize(0)}px`;
80
- //
81
- // Resize state and handlers
82
- //
83
- this.colSizes = {};
84
- this.rowSizes = {};
85
- this.resizing = null;
86
- this.handlePointerDown = (event) => {
87
- const actionEl = event.target?.closest("[data-dx-grid-action]");
88
- const action = actionEl?.getAttribute("data-dx-grid-action");
89
- if (action) {
90
- if (action.startsWith("resize")) {
91
- const [resize, index] = action.split(",");
92
- const [_, axis] = resize.split("-");
93
- this.resizing = {
94
- axis,
95
- size: axis === "col" ? this.colSize(index) : this.rowSize(index),
96
- page: getPage(axis, event),
97
- index
98
- };
99
- }
100
- }
101
- };
102
- this.handlePointerUp = (_event) => {
103
- this.resizing = null;
104
- };
105
- this.handlePointerMove = (event) => {
106
- if (this.resizing) {
107
- const delta = getPage(this.resizing.axis, event) - this.resizing.page;
108
- if (this.resizing.axis === "col") {
109
- const nextSize = Math.max(sizeColMin, Math.min(sizeColMax, this.resizing.size + delta));
110
- this.colSizes = {
111
- ...this.colSizes,
112
- [this.resizing.index]: nextSize
113
- };
114
- this.updateVisInline();
115
- } else {
116
- const nextSize = Math.max(sizeRowMin, Math.min(sizeRowMax, this.resizing.size + delta));
117
- this.rowSizes = {
118
- ...this.rowSizes,
119
- [this.resizing.index]: nextSize
120
- };
121
- this.updateVisBlock();
122
- }
123
- }
124
- };
125
- //
126
- // Resize & reposition handlers, observer, ref
127
- //
46
+ this.cellByPosition = {};
128
47
  this.observer = new ResizeObserver((entries) => {
129
48
  const { inlineSize, blockSize } = entries?.[0]?.contentBoxSize?.[0] ?? {
130
49
  inlineSize: 0,
131
50
  blockSize: 0
132
51
  };
133
- if (Math.abs(inlineSize - this.sizeInline) > resizeTolerance || Math.abs(blockSize - this.sizeBlock) > resizeTolerance) {
134
- this.sizeInline = inlineSize;
135
- this.sizeBlock = blockSize;
136
- this.updateVis();
137
- }
52
+ this.sizeInline = inlineSize;
53
+ this.sizeBlock = blockSize;
138
54
  });
139
55
  this.viewportRef = createRef();
140
56
  this.handleWheel = ({ deltaX, deltaY }) => {
141
57
  this.posInline = Math.max(0, this.posInline + deltaX);
142
58
  this.posBlock = Math.max(0, this.posBlock + deltaY);
143
- if (this.posInline >= this.binInlineMin && this.posInline < this.binInlineMax && this.posBlock >= this.binBlockMin && this.posBlock < this.binBlockMax) {
144
- } else {
145
- this.updateVis();
146
- }
147
59
  };
148
60
  }
149
- //
150
- // Accessors
151
- //
152
- colSize(c) {
153
- return this.colSizes?.[c] ?? this.columnDefault.size;
154
- }
155
- rowSize(r) {
156
- return this.rowSizes?.[r] ?? this.rowDefault.size;
61
+ willUpdate(changed) {
62
+ if (changed.has("values")) {
63
+ this.cellByPosition = Object.entries(this.values).reduce((acc, [id, { pos, end }]) => {
64
+ const { i: i1, j: j1 } = posFromNumericNotation(pos);
65
+ if (end) {
66
+ const { i: i2, j: j2 } = posFromNumericNotation(end);
67
+ for (let ci = i1; ci <= i2; ci += 1) {
68
+ for (let cj = j1; cj <= j2; cj += 1) {
69
+ acc[`${ci},${cj}`] = id;
70
+ }
71
+ }
72
+ } else {
73
+ acc[`${i1},${j1}`] = id;
74
+ }
75
+ return acc;
76
+ }, {});
77
+ }
157
78
  }
158
- getCell(c, r) {
159
- return this.cells[`${c}${separator}${r}`];
79
+ getCell(i, j) {
80
+ const pos = `${i},${j}`;
81
+ const cellId = this.cellByPosition[pos];
82
+ return cellId ? this.values[cellId] : void 0;
160
83
  }
161
- updateVisInline() {
162
- let colIndex = 0;
163
- let pxInline = this.colSize(colIndex);
164
- while (pxInline < this.posInline) {
165
- colIndex += 1;
166
- pxInline += this.colSize(colIndex) + gap;
167
- }
168
- this.visColMin = colIndex - overscanCol;
169
- this.binInlineMin = pxInline - this.colSize(colIndex) - gap;
170
- this.binInlineMax = pxInline + gap;
171
- this.overscanInline = [
172
- ...Array(overscanCol)
173
- ].reduce((acc, _, c0) => {
174
- acc += this.colSize(this.visColMin + c0);
84
+ computeExtrema() {
85
+ const colVisMin = Math.floor(this.posInline / (colSize + gap));
86
+ const colVisMax = Math.ceil((this.sizeInline + this.posInline) / (colSize + gap));
87
+ const rowVisMin = Math.floor(this.posBlock / (rowSize + gap));
88
+ const rowVisMax = Math.ceil((this.sizeBlock + this.posBlock) / (rowSize + gap));
89
+ const { colExtMin, colExtMax } = [
90
+ ...Array(rowVisMax - rowVisMin)
91
+ ].reduce((acc, _, j) => {
92
+ const colVisMinCell = this.getCell(colVisMin, j + rowVisMin);
93
+ if (colVisMinCell?.end) {
94
+ const { i: iStart } = posFromNumericNotation(colVisMinCell.pos);
95
+ acc.colExtMin = Math.min(acc.colExtMin, iStart);
96
+ }
97
+ const colVisMaxCell = this.getCell(colVisMax, j + rowVisMin);
98
+ if (colVisMaxCell?.end) {
99
+ const { i: iEnd } = posFromNumericNotation(colVisMaxCell.end);
100
+ acc.colExtMax = Math.max(acc.colExtMax, iEnd);
101
+ }
175
102
  return acc;
176
- }, 0) + gap * (overscanCol - 1);
177
- while (pxInline < this.binInlineMax + this.sizeInline) {
178
- colIndex += 1;
179
- pxInline += this.colSize(colIndex) + gap;
180
- }
181
- this.visColMax = colIndex + overscanCol + 1;
182
- this.templateColumns = [
183
- ...Array(this.visColMax - this.visColMin)
184
- ].map((_, c0) => `${this.colSize(this.visColMin + c0)}px`).join(" ");
185
- }
186
- updateVisBlock() {
187
- let rowIndex = 0;
188
- let pxBlock = this.rowSize(rowIndex);
189
- while (pxBlock < this.posBlock) {
190
- rowIndex += 1;
191
- pxBlock += this.rowSize(rowIndex) + gap;
192
- }
193
- this.visRowMin = rowIndex - overscanRow;
194
- this.binBlockMin = pxBlock - this.rowSize(rowIndex) - gap;
195
- this.binBlockMax = pxBlock + gap;
196
- this.overscanBlock = [
197
- ...Array(overscanRow)
198
- ].reduce((acc, _, r0) => {
199
- acc += this.rowSize(this.visRowMin + r0);
103
+ }, {
104
+ colExtMin: colVisMin,
105
+ colExtMax: colVisMax
106
+ });
107
+ const { rowExtMin, rowExtMax } = [
108
+ ...Array(colVisMax - colVisMin)
109
+ ].reduce((acc, _, i) => {
110
+ const rowVisMinCell = this.getCell(i + colVisMin, rowVisMin);
111
+ if (rowVisMinCell?.end) {
112
+ const { j: jStart } = posFromNumericNotation(rowVisMinCell.pos);
113
+ acc.rowExtMin = Math.min(acc.rowExtMin, jStart);
114
+ }
115
+ const rowVisMaxCell = this.getCell(i + colVisMin, rowVisMax);
116
+ if (rowVisMaxCell?.end) {
117
+ const { j: jEnd } = posFromNumericNotation(rowVisMaxCell.end);
118
+ acc.rowExtMax = Math.max(acc.rowExtMax, jEnd);
119
+ }
200
120
  return acc;
201
- }, 0) + gap * (overscanRow - 1);
202
- while (pxBlock < this.binBlockMax + this.sizeBlock) {
203
- rowIndex += 1;
204
- pxBlock += this.rowSize(rowIndex) + gap;
205
- }
206
- this.visRowMax = rowIndex + overscanRow + 1;
207
- this.templateRows = [
208
- ...Array(this.visRowMax - this.visRowMin)
209
- ].map((_, r0) => `${this.rowSize(this.visRowMin + r0)}px`).join(" ");
210
- }
211
- updateVis() {
212
- this.updateVisInline();
213
- this.updateVisBlock();
121
+ }, {
122
+ rowExtMin: rowVisMin,
123
+ rowExtMax: rowVisMax
124
+ });
125
+ return {
126
+ colVisMin,
127
+ colExtMin,
128
+ colVisMax,
129
+ colExtMax,
130
+ rowVisMin,
131
+ rowExtMin,
132
+ rowVisMax,
133
+ rowExtMax
134
+ };
214
135
  }
215
- //
216
- // Render and other lifecycle methods
217
- //
218
136
  render() {
219
- const visibleCols = this.visColMax - this.visColMin;
220
- const visibleRows = this.visRowMax - this.visRowMin;
221
- const offsetInline = this.binInlineMin - this.posInline - this.overscanInline;
222
- const offsetBlock = this.binBlockMin - this.posBlock - this.overscanBlock;
223
- return html`<div
224
- role="none"
225
- class="dx-grid"
226
- @pointerdown=${this.handlePointerDown}
227
- @pointerup=${this.handlePointerUp}
228
- @pointermove=${this.handlePointerMove}
229
- >
137
+ const { colVisMin, colVisMax, rowVisMin, rowVisMax } = this.computeExtrema();
138
+ const visibleCols = colVisMax - colVisMin;
139
+ const visibleRows = rowVisMax - rowVisMin;
140
+ const offsetInline = colVisMin * colSize - this.posInline;
141
+ const offsetBlock = rowVisMin * rowSize - this.posBlock;
142
+ return html`<div role="none" class="dx-grid">
230
143
  <div role="none" class="dx-grid__corner"></div>
231
144
  <div role="none" class="dx-grid__columnheader">
232
145
  <div
233
146
  role="none"
234
147
  class="dx-grid__columnheader__content"
235
- style="transform:translate3d(${offsetInline}px,0,0);grid-template-columns:${this.templateColumns};"
148
+ style="transform:translate3d(${offsetInline}px,0,0);grid-template-columns:repeat(${visibleCols},${colSize}px);"
236
149
  >
237
150
  ${[
238
151
  ...Array(visibleCols)
239
- ].map((_, c0) => {
240
- const c = this.visColMin + c0;
152
+ ].map((_, i) => {
241
153
  return html`<div
242
- role="columnheader"
243
- ?inert=${c < 0}
244
- style="inline-size:${this.colSize(c)}px;block-size:${this.rowDefault.size}px;grid-column:${c0 + 1}/${c0 + 2};"
154
+ role="gridcell"
155
+ style="inline-size:${colSize}px;block-size:${rowSize}px;grid-column:${i + 1}/${i + 2};"
245
156
  >
246
- <span id=${localChId(c0)}>${colToA1Notation(c)}</span>
247
- ${(this.columns[c]?.resizeable ?? this.columnDefault.resizeable) && html`<button class="dx-grid__resize-handle" data-dx-grid-action=${`resize-col,${c}`}>
248
- <span class="sr-only">Resize</span>
249
- </button>`}
157
+ ${colToA1Notation(colVisMin + i)}
250
158
  </div>`;
251
159
  })}
252
160
  </div>
@@ -256,17 +164,9 @@ var DxGrid = class extends LitElement {
256
164
  <div role="none" class="dx-grid__rowheader__content" style="transform:translate3d(0,${offsetBlock}px,0);">
257
165
  ${[
258
166
  ...Array(visibleRows)
259
- ].map((_, r0) => {
260
- const r = this.visRowMin + r0;
261
- return html`<div
262
- role="rowheader"
263
- ?inert=${r < 0}
264
- style="block-size:${this.rowSize(r)}px;grid-row:${r0 + 1}/${r0 + 2}"
265
- >
266
- <span id=${localRhId(r0)}>${rowToA1Notation(r)}</span>
267
- ${(this.rows[r]?.resizeable ?? this.rowDefault.resizeable) && html`<button class="dx-grid__resize-handle" data-dx-grid-action=${`resize-row,${r}`}>
268
- <span class="sr-only">Resize</span>
269
- </button>`}
167
+ ].map((_, j) => {
168
+ return html`<div role="gridcell" style="block-size:${rowSize}px;grid-row:${j + 1}/${j + 2}">
169
+ ${rowToA1Notation(rowVisMin + j)}
270
170
  </div>`;
271
171
  })}
272
172
  </div>
@@ -275,27 +175,32 @@ var DxGrid = class extends LitElement {
275
175
  <div
276
176
  role="grid"
277
177
  class="dx-grid__content"
278
- style="transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this.templateColumns};grid-template-rows:${this.templateRows};"
178
+ style="transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:repeat(${visibleCols},${colSize}px);grid-template-rows:repeat(${visibleRows},${rowSize}px);"
279
179
  >
280
180
  ${[
281
181
  ...Array(visibleCols)
282
- ].map((_, c0) => {
182
+ ].map((_, i) => {
283
183
  return [
284
184
  ...Array(visibleRows)
285
- ].map((_2, r0) => {
286
- const c = c0 + this.visColMin;
287
- const r = r0 + this.visRowMin;
288
- const cell = this.getCell(c, r);
289
- return html`<div
290
- role="gridcell"
291
- ?inert=${c < 0 || r < 0}
292
- aria-rowindex=${r}
293
- aria-colindex=${c}
294
- data-dx-grid-action="cell"
295
- style="grid-column:${c0 + 1};grid-row:${r0 + 1}"
296
- >
297
- ${cell?.value}
298
- </div>`;
185
+ ].map((_2, j) => {
186
+ const posAbs = `${i + colVisMin},${j + rowVisMin}`;
187
+ const cellId = this.cellByPosition[posAbs];
188
+ const cell = cellId ? this.values[cellId] : void 0;
189
+ if (cell?.end) {
190
+ if (posAbs !== cell?.pos) {
191
+ return null;
192
+ } else {
193
+ const { i: iEndAbs, j: jEndAbs } = posFromNumericNotation(cell.end);
194
+ return html`<div
195
+ role="gridcell"
196
+ style="grid-column:${i + 1} / ${iEndAbs - colVisMin + 2};grid-row:${j + 1} / ${jEndAbs - rowVisMin + 2}"
197
+ >
198
+ ${cell?.value}
199
+ </div>`;
200
+ }
201
+ } else {
202
+ return html`<div role="gridcell" style="grid-column:${i + 1};grid-row:${j + 1}">${cell?.value}</div>`;
203
+ }
299
204
  });
300
205
  })}
301
206
  </div>
@@ -312,18 +217,6 @@ var DxGrid = class extends LitElement {
312
217
  }
313
218
  firstUpdated() {
314
219
  this.observer.observe(this.viewportRef.value);
315
- this.colSizes = Object.entries(this.columns).reduce((acc, [colId, colMeta]) => {
316
- if (colMeta?.size) {
317
- acc[colId] = colMeta.size;
318
- }
319
- return acc;
320
- }, {});
321
- this.rowSizes = Object.entries(this.rows).reduce((acc, [rowId, rowMeta]) => {
322
- if (rowMeta?.size) {
323
- acc[rowId] = rowMeta.size;
324
- }
325
- return acc;
326
- }, {});
327
220
  }
328
221
  disconnectedCallback() {
329
222
  super.disconnectedCallback();
@@ -339,27 +232,7 @@ _ts_decorate([
339
232
  property({
340
233
  type: Object
341
234
  })
342
- ], DxGrid.prototype, "rowDefault", void 0);
343
- _ts_decorate([
344
- property({
345
- type: Object
346
- })
347
- ], DxGrid.prototype, "columnDefault", void 0);
348
- _ts_decorate([
349
- property({
350
- type: Object
351
- })
352
- ], DxGrid.prototype, "rows", void 0);
353
- _ts_decorate([
354
- property({
355
- type: Object
356
- })
357
- ], DxGrid.prototype, "columns", void 0);
358
- _ts_decorate([
359
- property({
360
- type: Object
361
- })
362
- ], DxGrid.prototype, "cells", void 0);
235
+ ], DxGrid.prototype, "values", void 0);
363
236
  _ts_decorate([
364
237
  state()
365
238
  ], DxGrid.prototype, "posInline", void 0);
@@ -374,49 +247,7 @@ _ts_decorate([
374
247
  ], DxGrid.prototype, "sizeBlock", void 0);
375
248
  _ts_decorate([
376
249
  state()
377
- ], DxGrid.prototype, "overscanInline", void 0);
378
- _ts_decorate([
379
- state()
380
- ], DxGrid.prototype, "overscanBlock", void 0);
381
- _ts_decorate([
382
- state()
383
- ], DxGrid.prototype, "binInlineMin", void 0);
384
- _ts_decorate([
385
- state()
386
- ], DxGrid.prototype, "binInlineMax", void 0);
387
- _ts_decorate([
388
- state()
389
- ], DxGrid.prototype, "binBlockMin", void 0);
390
- _ts_decorate([
391
- state()
392
- ], DxGrid.prototype, "binBlockMax", void 0);
393
- _ts_decorate([
394
- state()
395
- ], DxGrid.prototype, "visColMin", void 0);
396
- _ts_decorate([
397
- state()
398
- ], DxGrid.prototype, "visColMax", void 0);
399
- _ts_decorate([
400
- state()
401
- ], DxGrid.prototype, "visRowMin", void 0);
402
- _ts_decorate([
403
- state()
404
- ], DxGrid.prototype, "visRowMax", void 0);
405
- _ts_decorate([
406
- state()
407
- ], DxGrid.prototype, "templateColumns", void 0);
408
- _ts_decorate([
409
- state()
410
- ], DxGrid.prototype, "templateRows", void 0);
411
- _ts_decorate([
412
- state()
413
- ], DxGrid.prototype, "colSizes", void 0);
414
- _ts_decorate([
415
- state()
416
- ], DxGrid.prototype, "rowSizes", void 0);
417
- _ts_decorate([
418
- state()
419
- ], DxGrid.prototype, "resizing", void 0);
250
+ ], DxGrid.prototype, "cellByPosition", void 0);
420
251
  _ts_decorate([
421
252
  state()
422
253
  ], DxGrid.prototype, "observer", void 0);