@dxos/lit-grid 0.6.12-main.2d19bf1 → 0.6.12-main.5a87ad5

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.
Files changed (56) hide show
  1. package/dist/lib/browser/index.mjs +936 -0
  2. package/dist/lib/browser/index.mjs.map +7 -0
  3. package/dist/lib/browser/meta.json +1 -0
  4. package/dist/types/src/dx-grid-axis-resize-handle.d.ts +1 -2
  5. package/dist/types/src/dx-grid-axis-resize-handle.d.ts.map +1 -1
  6. package/dist/types/src/dx-grid.d.ts +7 -42
  7. package/dist/types/src/dx-grid.d.ts.map +1 -1
  8. package/dist/types/src/dx-grid.lit-stories.d.ts +1 -23
  9. package/dist/types/src/dx-grid.lit-stories.d.ts.map +1 -1
  10. package/dist/types/src/types.d.ts +13 -45
  11. package/dist/types/src/types.d.ts.map +1 -1
  12. package/dist/types/src/util.d.ts +2 -4
  13. package/dist/types/src/util.d.ts.map +1 -1
  14. package/package.json +7 -5
  15. package/src/dx-grid-axis-resize-handle.ts +2 -6
  16. package/src/dx-grid.lit-stories.ts +16 -140
  17. package/src/dx-grid.pcss +62 -38
  18. package/src/dx-grid.ts +280 -659
  19. package/src/types.ts +11 -55
  20. package/src/util.ts +2 -18
  21. package/dist/src/dx-grid-axis-resize-handle.d.ts +0 -16
  22. package/dist/src/dx-grid-axis-resize-handle.d.ts.map +0 -1
  23. package/dist/src/dx-grid-axis-resize-handle.js +0 -96
  24. package/dist/src/dx-grid-axis-resize-handle.js.map +0 -1
  25. package/dist/src/dx-grid.d.ts +0 -116
  26. package/dist/src/dx-grid.d.ts.map +0 -1
  27. package/dist/src/dx-grid.js +0 -1054
  28. package/dist/src/dx-grid.js.map +0 -1
  29. package/dist/src/dx-grid.lit-stories.d.ts +0 -42
  30. package/dist/src/dx-grid.lit-stories.d.ts.map +0 -1
  31. package/dist/src/dx-grid.lit-stories.js +0 -166
  32. package/dist/src/dx-grid.lit-stories.js.map +0 -1
  33. package/dist/src/index.d.ts +0 -3
  34. package/dist/src/index.d.ts.map +0 -1
  35. package/dist/src/index.js +0 -6
  36. package/dist/src/index.js.map +0 -1
  37. package/dist/src/types.d.ts +0 -106
  38. package/dist/src/types.d.ts.map +0 -1
  39. package/dist/src/types.js +0 -44
  40. package/dist/src/types.js.map +0 -1
  41. package/dist/src/util.d.ts +0 -9
  42. package/dist/src/util.d.ts.map +0 -1
  43. package/dist/src/util.js +0 -19
  44. package/dist/src/util.js.map +0 -1
  45. package/dist/types/src/dx-grid-axis-resize-handle.js +0 -96
  46. package/dist/types/src/dx-grid-axis-resize-handle.js.map +0 -1
  47. package/dist/types/src/dx-grid.js +0 -1054
  48. package/dist/types/src/dx-grid.js.map +0 -1
  49. package/dist/types/src/dx-grid.lit-stories.js +0 -166
  50. package/dist/types/src/dx-grid.lit-stories.js.map +0 -1
  51. package/dist/types/src/index.js +0 -6
  52. package/dist/types/src/index.js.map +0 -1
  53. package/dist/types/src/types.js +0 -44
  54. package/dist/types/src/types.js.map +0 -1
  55. package/dist/types/src/util.js +0 -19
  56. package/dist/types/src/util.js.map +0 -1
@@ -0,0 +1,936 @@
1
+ // packages/ui/lit-grid/src/dx-grid.ts
2
+ import { LitElement as LitElement2, html as html2, nothing } from "lit";
3
+ import { customElement as customElement2, state, property as property2, eventOptions } from "lit/decorators.js";
4
+ import { ref as ref2, createRef } from "lit/directives/ref.js";
5
+
6
+ // packages/ui/lit-grid/src/dx-grid-axis-resize-handle.ts
7
+ import { draggable } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
8
+ import { disableNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview";
9
+ import { preventUnhandled } from "@atlaskit/pragmatic-drag-and-drop/prevent-unhandled";
10
+ import { html, LitElement } from "lit";
11
+ import { customElement, property } from "lit/decorators.js";
12
+ import { ref } from "lit/directives/ref.js";
13
+
14
+ // packages/ui/lit-grid/src/util.ts
15
+ var separator = ",";
16
+ var toCellIndex = (cellCoords) => `${cellCoords.col}${separator}${cellCoords.row}`;
17
+
18
+ // packages/ui/lit-grid/src/types.ts
19
+ var DxAxisResize = class extends Event {
20
+ constructor(props) {
21
+ super("dx-axis-resize");
22
+ this.axis = props.axis;
23
+ this.index = props.index;
24
+ this.size = props.size;
25
+ }
26
+ };
27
+ var DxAxisResizeInternal = class extends Event {
28
+ constructor(props) {
29
+ super("dx-axis-resize-internal", {
30
+ composed: true,
31
+ bubbles: true
32
+ });
33
+ this.axis = props.axis;
34
+ this.index = props.index;
35
+ this.size = props.size;
36
+ this.delta = props.delta;
37
+ this.state = props.state;
38
+ }
39
+ };
40
+ var DxEditRequest = class extends Event {
41
+ constructor(props) {
42
+ super("dx-edit-request");
43
+ this.cellIndex = props.cellIndex;
44
+ this.cellBox = props.cellBox;
45
+ this.initialContent = props.initialContent;
46
+ }
47
+ };
48
+ var DxGridCellsSelect = class extends Event {
49
+ constructor({ start, end }) {
50
+ super("dx-grid-cells-select");
51
+ this.start = toCellIndex(start);
52
+ this.end = toCellIndex(end);
53
+ this.minCol = Math.min(start.col, end.col);
54
+ this.maxCol = Math.max(start.col, end.col);
55
+ this.minRow = Math.min(start.row, end.row);
56
+ this.maxRow = Math.max(start.row, end.row);
57
+ }
58
+ };
59
+
60
+ // packages/ui/lit-grid/src/dx-grid-axis-resize-handle.ts
61
+ function _ts_decorate(decorators, target, key, desc) {
62
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
63
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
64
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
65
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
66
+ }
67
+ var DxGridAxisResizeHandle = class extends LitElement {
68
+ constructor() {
69
+ super(...arguments);
70
+ this.axis = "row";
71
+ this.index = "-1";
72
+ this.size = 128;
73
+ this.dragStartSize = 128;
74
+ this.cleanup = null;
75
+ }
76
+ render() {
77
+ return html`<button class="dx-grid__resize-handle" ${ref(this.mount)}>
78
+ <span class="sr-only">Resize</span>
79
+ </button>`;
80
+ }
81
+ dispatchResize(location, state2) {
82
+ const client = this.axis === "row" ? "clientY" : "clientX";
83
+ const event = new DxAxisResizeInternal({
84
+ axis: this.axis,
85
+ size: this.dragStartSize,
86
+ index: this.index,
87
+ delta: location.current.input[client] - location.initial.input[client],
88
+ state: state2
89
+ });
90
+ this.dispatchEvent(event);
91
+ }
92
+ mount(element) {
93
+ this.cleanup?.();
94
+ const host = this;
95
+ if (element) {
96
+ this.cleanup = draggable({
97
+ element,
98
+ onGenerateDragPreview: ({ nativeSetDragImage }) => {
99
+ disableNativeDragPreview({
100
+ nativeSetDragImage
101
+ });
102
+ preventUnhandled.start();
103
+ },
104
+ onDragStart() {
105
+ host.dragStartSize = host.size;
106
+ },
107
+ onDrag({ location }) {
108
+ host.dispatchResize(location, "dragging");
109
+ },
110
+ onDrop({ location }) {
111
+ host.dispatchResize(location, "dropped");
112
+ }
113
+ });
114
+ }
115
+ }
116
+ disconnectedCallback() {
117
+ super.disconnectedCallback();
118
+ this.cleanup?.();
119
+ }
120
+ createRenderRoot() {
121
+ return this;
122
+ }
123
+ };
124
+ _ts_decorate([
125
+ property({
126
+ type: String
127
+ })
128
+ ], DxGridAxisResizeHandle.prototype, "axis", void 0);
129
+ _ts_decorate([
130
+ property({
131
+ type: String
132
+ })
133
+ ], DxGridAxisResizeHandle.prototype, "index", void 0);
134
+ _ts_decorate([
135
+ property({
136
+ type: Number
137
+ })
138
+ ], DxGridAxisResizeHandle.prototype, "size", void 0);
139
+ DxGridAxisResizeHandle = _ts_decorate([
140
+ customElement("dx-grid-axis-resize-handle")
141
+ ], DxGridAxisResizeHandle);
142
+
143
+ // packages/ui/lit-grid/src/dx-grid.ts
144
+ function _ts_decorate2(decorators, target, key, desc) {
145
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
146
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
147
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
148
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
149
+ }
150
+ var gap = 1;
151
+ var resizeTolerance = 8;
152
+ var overscanCol = 1;
153
+ var overscanRow = 1;
154
+ var sizeColMin = 32;
155
+ var sizeColMax = 1024;
156
+ var sizeRowMin = 16;
157
+ var sizeRowMax = 1024;
158
+ var colToA1Notation = (col) => {
159
+ return (col >= 26 ? String.fromCharCode("A".charCodeAt(0) + Math.floor(col / 26) - 1) : "") + String.fromCharCode("A".charCodeAt(0) + col % 26);
160
+ };
161
+ var rowToA1Notation = (row) => {
162
+ return `${row + 1}`;
163
+ };
164
+ var closestAction = (target) => {
165
+ const actionEl = target?.closest("[data-dx-grid-action]") ?? null;
166
+ return {
167
+ actionEl,
168
+ action: actionEl?.getAttribute("data-dx-grid-action") ?? null
169
+ };
170
+ };
171
+ var closestCell = (target, actionEl) => {
172
+ let cellElement = actionEl;
173
+ if (!cellElement) {
174
+ const { action, actionEl: actionEl2 } = closestAction(target);
175
+ if (action === "cell") {
176
+ cellElement = actionEl2;
177
+ }
178
+ }
179
+ if (cellElement) {
180
+ const col = parseInt(cellElement.getAttribute("aria-colindex") ?? "never");
181
+ const row = parseInt(cellElement.getAttribute("aria-rowindex") ?? "never");
182
+ return {
183
+ col,
184
+ row
185
+ };
186
+ } else {
187
+ return null;
188
+ }
189
+ };
190
+ var isSameCell = (a, b) => a && b && Number.isFinite(a.col) && Number.isFinite(a.row) && a.col === b.col && a.row === b.row;
191
+ var localChId = (c0) => `ch--${c0}`;
192
+ var localRhId = (r0) => `rh--${r0}`;
193
+ var getPage = (axis, event) => axis === "col" ? event.pageX : event.pageY;
194
+ var DxGrid = class extends LitElement2 {
195
+ constructor() {
196
+ super();
197
+ this.gridId = "default-grid-id";
198
+ this.rowDefault = {
199
+ size: 32
200
+ };
201
+ this.columnDefault = {
202
+ size: 180
203
+ };
204
+ this.rows = {};
205
+ this.columns = {};
206
+ this.initialCells = {};
207
+ this.mode = "browse";
208
+ /**
209
+ * When this function is defined, it is used first to try to get a value for a cell, and otherwise will fall back
210
+ * to `cells`.
211
+ */
212
+ this.getCells = null;
213
+ this.cells = {};
214
+ //
215
+ // `pos`, short for ‘position’, is the position in pixels of the viewport from the origin.
216
+ //
217
+ this.posInline = 0;
218
+ this.posBlock = 0;
219
+ //
220
+ // `size` (when not suffixed with ‘row’ or ‘col’, see above) is the size in pixels of the viewport.
221
+ //
222
+ this.sizeInline = 0;
223
+ this.sizeBlock = 0;
224
+ //
225
+ // `overscan` is the amount in pixels to offset the grid content due to the number of overscanned columns or rows.
226
+ //
227
+ this.overscanInline = 0;
228
+ this.overscanBlock = 0;
229
+ //
230
+ // `bin`, not short for anything, is the range in pixels within which virtualization does not need to reassess.
231
+ //
232
+ this.binInlineMin = 0;
233
+ this.binInlineMax = this.colSize(0);
234
+ this.binBlockMin = 0;
235
+ this.binBlockMax = this.rowSize(0);
236
+ //
237
+ // `vis`, short for ‘visible’, is the range in numeric index of the columns or rows which should be rendered within
238
+ // the viewport. These start with naïve values that are updated before first contentful render.
239
+ //
240
+ this.visColMin = 0;
241
+ this.visColMax = 1;
242
+ this.visRowMin = 0;
243
+ this.visRowMax = 1;
244
+ //
245
+ // `template` is the rendered value of `grid-{axis}-template`.
246
+ //
247
+ this.templateColumns = `${this.colSize(0)}px`;
248
+ this.templateRows = `${this.rowSize(0)}px`;
249
+ //
250
+ // Focus, selection, and resize states
251
+ //
252
+ this.pointer = null;
253
+ this.colSizes = {};
254
+ this.rowSizes = {};
255
+ this.focusActive = false;
256
+ this.focusedCell = {
257
+ col: 0,
258
+ row: 0
259
+ };
260
+ this.selectionStart = {
261
+ col: 0,
262
+ row: 0
263
+ };
264
+ this.selectionEnd = {
265
+ col: 0,
266
+ row: 0
267
+ };
268
+ this.handlePointerDown = (event) => {
269
+ if (event.isPrimary) {
270
+ const { action, actionEl } = closestAction(event.target);
271
+ if (action) {
272
+ if (action.startsWith("resize") && this.mode === "browse") {
273
+ const [resize, index] = action.split(",");
274
+ const [_, axis] = resize.split("-");
275
+ this.pointer = {
276
+ state: "resizing",
277
+ axis,
278
+ size: axis === "col" ? this.colSize(index) : this.rowSize(index),
279
+ page: getPage(axis, event),
280
+ index
281
+ };
282
+ } else if (action === "cell") {
283
+ const cellCoords = closestCell(event.target, actionEl);
284
+ if (cellCoords) {
285
+ this.pointer = {
286
+ state: "selecting"
287
+ };
288
+ this.selectionStart = cellCoords;
289
+ }
290
+ if (this.mode === "edit") {
291
+ event.preventDefault();
292
+ } else {
293
+ if (this.focusActive && isSameCell(this.focusedCell, cellCoords)) {
294
+ this.dispatchEditRequest();
295
+ }
296
+ }
297
+ }
298
+ }
299
+ }
300
+ };
301
+ this.handlePointerUp = (event) => {
302
+ if (this.pointer?.state === "resizing") {
303
+ } else {
304
+ const cell = closestCell(event.target);
305
+ if (cell) {
306
+ this.selectionEnd = cell;
307
+ this.dispatchEvent(new DxGridCellsSelect({
308
+ start: this.selectionStart,
309
+ end: this.selectionEnd
310
+ }));
311
+ }
312
+ }
313
+ this.pointer = null;
314
+ };
315
+ this.handlePointerMove = (event) => {
316
+ if (this.pointer?.state === "selecting") {
317
+ const cell = closestCell(event.target);
318
+ if (cell && (cell.col !== this.selectionEnd.col || cell.row !== this.selectionEnd.row)) {
319
+ this.selectionEnd = cell;
320
+ }
321
+ }
322
+ };
323
+ //
324
+ // Resize & reposition handlers, observer, ref
325
+ //
326
+ this.observer = new ResizeObserver((entries) => {
327
+ const { inlineSize, blockSize } = entries?.[0]?.contentBoxSize?.[0] ?? {
328
+ inlineSize: 0,
329
+ blockSize: 0
330
+ };
331
+ if (Math.abs(inlineSize - this.sizeInline) > resizeTolerance || Math.abs(blockSize - this.sizeBlock) > resizeTolerance) {
332
+ this.sizeInline = inlineSize;
333
+ this.sizeBlock = blockSize;
334
+ this.updateVis();
335
+ }
336
+ });
337
+ this.viewportRef = createRef();
338
+ this.maybeUpdateVis = () => {
339
+ if (this.posInline >= this.binInlineMin && this.posInline < this.binInlineMax && this.posBlock >= this.binBlockMin && this.posBlock < this.binBlockMax) {
340
+ } else {
341
+ this.updateVis();
342
+ }
343
+ };
344
+ this.handleWheel = ({ deltaX, deltaY }) => {
345
+ if (this.mode === "browse") {
346
+ this.posInline = Math.max(0, this.posInline + deltaX);
347
+ this.posBlock = Math.max(0, this.posBlock + deltaY);
348
+ this.maybeUpdateVis();
349
+ }
350
+ };
351
+ this.addEventListener("dx-axis-resize-internal", this.handleAxisResizeInternal);
352
+ this.addEventListener("wheel", this.handleWheel);
353
+ this.addEventListener("pointerdown", this.handlePointerDown);
354
+ this.addEventListener("pointermove", this.handlePointerMove);
355
+ this.addEventListener("pointerup", this.handlePointerUp);
356
+ this.addEventListener("pointerleave", this.handlePointerUp);
357
+ this.addEventListener("focus", this.handleFocus, {
358
+ capture: true
359
+ });
360
+ this.addEventListener("blur", this.handleBlur, {
361
+ capture: true
362
+ });
363
+ this.addEventListener("keydown", this.handleKeydown);
364
+ }
365
+ //
366
+ // Primary pointer and keyboard handlers
367
+ //
368
+ dispatchEditRequest(initialContent) {
369
+ this.snapPosToFocusedCell();
370
+ queueMicrotask(() => this.dispatchEvent(new DxEditRequest({
371
+ cellIndex: toCellIndex(this.focusedCell),
372
+ cellBox: this.focusedCellBox(),
373
+ initialContent
374
+ })));
375
+ }
376
+ handleKeydown(event) {
377
+ if (this.focusActive && this.mode === "browse") {
378
+ switch (event.key) {
379
+ case "ArrowDown":
380
+ this.focusedCell = {
381
+ ...this.focusedCell,
382
+ row: this.focusedCell.row + 1
383
+ };
384
+ break;
385
+ case "ArrowUp":
386
+ this.focusedCell = {
387
+ ...this.focusedCell,
388
+ row: Math.max(0, this.focusedCell.row - 1)
389
+ };
390
+ break;
391
+ case "ArrowRight":
392
+ this.focusedCell = {
393
+ ...this.focusedCell,
394
+ col: this.focusedCell.col + 1
395
+ };
396
+ break;
397
+ case "ArrowLeft":
398
+ this.focusedCell = {
399
+ ...this.focusedCell,
400
+ col: Math.max(0, this.focusedCell.col - 1)
401
+ };
402
+ break;
403
+ }
404
+ switch (event.key) {
405
+ case "Enter":
406
+ this.dispatchEditRequest();
407
+ break;
408
+ default:
409
+ if (event.key.length === 1 && event.key.match(/\P{Cc}/u)) {
410
+ this.dispatchEditRequest(event.key);
411
+ }
412
+ break;
413
+ }
414
+ switch (event.key) {
415
+ case "ArrowDown":
416
+ case "ArrowUp":
417
+ case "ArrowRight":
418
+ case "ArrowLeft":
419
+ event.preventDefault();
420
+ this.snapPosToFocusedCell();
421
+ break;
422
+ }
423
+ }
424
+ }
425
+ //
426
+ // Accessors
427
+ //
428
+ colSize(c) {
429
+ return this.colSizes?.[c] ?? this.columnDefault.size;
430
+ }
431
+ rowSize(r) {
432
+ return this.rowSizes?.[r] ?? this.rowDefault.size;
433
+ }
434
+ cell(c, r) {
435
+ const index = `${c}${separator}${r}`;
436
+ return this.cells[index] ?? this.initialCells[index];
437
+ }
438
+ focusedCellBox() {
439
+ const cellElement = this.focusedCellElement();
440
+ const cellSize = {
441
+ inlineSize: this.colSize(this.focusedCell.col),
442
+ blockSize: this.rowSize(this.focusedCell.row)
443
+ };
444
+ if (!cellElement) {
445
+ return {
446
+ insetInlineStart: NaN,
447
+ insetBlockStart: NaN,
448
+ ...cellSize
449
+ };
450
+ }
451
+ const contentElement = cellElement.offsetParent;
452
+ const [_translate3d, inlineStr, blockStr] = contentElement.style.transform.split(/[()]|px,?\s?/);
453
+ const contentOffsetInline = parseFloat(inlineStr);
454
+ const contentOffsetBlock = parseFloat(blockStr);
455
+ const offsetParent = contentElement.offsetParent;
456
+ return {
457
+ insetInlineStart: cellElement.offsetLeft + contentOffsetInline + offsetParent.offsetLeft,
458
+ insetBlockStart: cellElement.offsetTop + contentOffsetBlock + offsetParent.offsetTop,
459
+ ...cellSize
460
+ };
461
+ }
462
+ updateVisInline() {
463
+ let colIndex = 0;
464
+ let pxInline = this.colSize(colIndex);
465
+ while (pxInline < this.posInline) {
466
+ colIndex += 1;
467
+ pxInline += this.colSize(colIndex) + gap;
468
+ }
469
+ this.visColMin = colIndex - overscanCol;
470
+ this.binInlineMin = pxInline - this.colSize(colIndex) - gap;
471
+ this.binInlineMax = pxInline + gap;
472
+ this.overscanInline = [
473
+ ...Array(overscanCol)
474
+ ].reduce((acc, _, c0) => {
475
+ acc += this.colSize(this.visColMin + c0);
476
+ return acc;
477
+ }, 0) + gap * (overscanCol - 1);
478
+ while (pxInline < this.binInlineMax + this.sizeInline + gap) {
479
+ colIndex += 1;
480
+ pxInline += this.colSize(colIndex) + gap;
481
+ }
482
+ this.visColMax = colIndex + overscanCol;
483
+ this.templateColumns = [
484
+ ...Array(this.visColMax - this.visColMin)
485
+ ].map((_, c0) => `${this.colSize(this.visColMin + c0)}px`).join(" ");
486
+ }
487
+ updateVisBlock() {
488
+ let rowIndex = 0;
489
+ let pxBlock = this.rowSize(rowIndex);
490
+ while (pxBlock < this.posBlock) {
491
+ rowIndex += 1;
492
+ pxBlock += this.rowSize(rowIndex) + gap;
493
+ }
494
+ this.visRowMin = rowIndex - overscanRow;
495
+ this.binBlockMin = pxBlock - this.rowSize(rowIndex) - gap;
496
+ this.binBlockMax = pxBlock + gap;
497
+ this.overscanBlock = [
498
+ ...Array(overscanRow)
499
+ ].reduce((acc, _, r0) => {
500
+ acc += this.rowSize(this.visRowMin + r0);
501
+ return acc;
502
+ }, 0) + gap * (overscanRow - 1);
503
+ while (pxBlock < this.binBlockMax + this.sizeBlock) {
504
+ rowIndex += 1;
505
+ pxBlock += this.rowSize(rowIndex) + gap;
506
+ }
507
+ this.visRowMax = rowIndex + overscanRow;
508
+ this.templateRows = [
509
+ ...Array(this.visRowMax - this.visRowMin)
510
+ ].map((_, r0) => `${this.rowSize(this.visRowMin + r0)}px`).join(" ");
511
+ }
512
+ updateVis() {
513
+ this.updateVisInline();
514
+ this.updateVisBlock();
515
+ }
516
+ // Focus handlers
517
+ handleFocus(event) {
518
+ const cellCoords = closestCell(event.target);
519
+ if (cellCoords) {
520
+ this.focusedCell = cellCoords;
521
+ this.focusActive = true;
522
+ }
523
+ }
524
+ handleBlur(event) {
525
+ if (!event.relatedTarget || !event.relatedTarget.closest(`[data-grid="${this.gridId}"]`)) {
526
+ this.focusActive = false;
527
+ }
528
+ }
529
+ focusedCellElement() {
530
+ return this.viewportRef.value?.querySelector(`[aria-colindex="${this.focusedCell.col}"][aria-rowindex="${this.focusedCell.row}"]`);
531
+ }
532
+ /**
533
+ * Moves focus to the cell with actual focus, otherwise moves focus to the viewport.
534
+ */
535
+ refocus(increment, delta = 1) {
536
+ switch (increment) {
537
+ case "row":
538
+ this.focusedCell = {
539
+ ...this.focusedCell,
540
+ row: this.focusedCell.row + delta
541
+ };
542
+ break;
543
+ case "col":
544
+ this.focusedCell = {
545
+ ...this.focusedCell,
546
+ col: this.focusedCell.col + delta
547
+ };
548
+ }
549
+ (this.focusedCell.row < this.visRowMin || this.focusedCell.row > this.visRowMax || this.focusedCell.col < this.visColMin || this.focusedCell.col > this.visColMax ? this.viewportRef.value : this.focusedCellElement())?.focus({
550
+ preventScroll: true
551
+ });
552
+ if (increment) {
553
+ this.snapPosToFocusedCell();
554
+ }
555
+ }
556
+ /**
557
+ * Updates `pos` so that a cell in focus is fully within the viewport
558
+ */
559
+ snapPosToFocusedCell() {
560
+ if (this.focusedCell.col < this.visColMin || this.focusedCell.col > this.visColMax || this.focusedCell.row < this.visRowMin || this.focusedCell.row > this.visRowMax) {
561
+ } else if (this.focusedCell.col > this.visColMin + overscanCol && this.focusedCell.col < this.visColMax - overscanCol - 1 && this.focusedCell.row > this.visRowMin + overscanRow && this.focusedCell.row < this.visRowMax - overscanRow - 1) {
562
+ } else {
563
+ if (this.focusedCell.col <= this.visColMin + overscanCol) {
564
+ this.posInline = this.binInlineMin;
565
+ this.updateVisInline();
566
+ } else if (this.focusedCell.col >= this.visColMax - overscanCol - 1) {
567
+ const sizeSumCol = [
568
+ ...Array(this.focusedCell.col - this.visColMin)
569
+ ].reduce((acc, _, c0) => {
570
+ acc += this.colSize(this.visColMin + overscanCol + c0) + gap;
571
+ return acc;
572
+ }, 0);
573
+ this.posInline = Math.max(0, this.binInlineMin + sizeSumCol + gap * 2 - this.sizeInline);
574
+ this.updateVisInline();
575
+ }
576
+ if (this.focusedCell.row <= this.visRowMin + overscanRow) {
577
+ this.posBlock = this.binBlockMin;
578
+ this.updateVisBlock();
579
+ } else if (this.focusedCell.row >= this.visRowMax - overscanRow - 1) {
580
+ const sizeSumRow = [
581
+ ...Array(this.focusedCell.row - this.visRowMin)
582
+ ].reduce((acc, _, r0) => {
583
+ acc += this.rowSize(this.visRowMin + overscanRow + r0) + gap;
584
+ return acc;
585
+ }, 0);
586
+ this.posBlock = Math.max(0, this.binBlockMin + sizeSumRow + gap * 2 - this.sizeBlock);
587
+ this.updateVisBlock();
588
+ }
589
+ }
590
+ }
591
+ //
592
+ // Map scroll DOM methods to virtualized value.
593
+ //
594
+ get scrollLeft() {
595
+ return this.posInline;
596
+ }
597
+ set scrollLeft(nextValue) {
598
+ this.posInline = nextValue;
599
+ this.maybeUpdateVis();
600
+ }
601
+ get scrollTop() {
602
+ return this.posBlock;
603
+ }
604
+ set scrollTop(nextValue) {
605
+ this.posBlock = nextValue;
606
+ this.maybeUpdateVis();
607
+ }
608
+ //
609
+ // Resize handlers
610
+ //
611
+ handleAxisResizeInternal(event) {
612
+ event.stopPropagation();
613
+ const { axis, delta, size, index, type } = event;
614
+ if (axis === "col") {
615
+ const nextSize = Math.max(sizeColMin, Math.min(sizeColMax, size + delta));
616
+ this.colSizes = {
617
+ ...this.colSizes,
618
+ [index]: nextSize
619
+ };
620
+ this.updateVisInline();
621
+ } else {
622
+ const nextSize = Math.max(sizeRowMin, Math.min(sizeRowMax, size + delta));
623
+ this.rowSizes = {
624
+ ...this.rowSizes,
625
+ [index]: nextSize
626
+ };
627
+ this.updateVisBlock();
628
+ }
629
+ if (type === "dropped") {
630
+ this.dispatchEvent(new DxAxisResize({
631
+ axis,
632
+ index,
633
+ size: this[axis === "col" ? "colSize" : "rowSize"](index)
634
+ }));
635
+ }
636
+ }
637
+ //
638
+ // Render and other lifecycle methods
639
+ //
640
+ render() {
641
+ const visibleCols = this.visColMax - this.visColMin;
642
+ const visibleRows = this.visRowMax - this.visRowMin;
643
+ const offsetInline = this.binInlineMin - this.posInline - this.overscanInline;
644
+ const offsetBlock = this.binBlockMin - this.posBlock - this.overscanBlock;
645
+ const selectColMin = Math.min(this.selectionStart.col, this.selectionEnd.col);
646
+ const selectColMax = Math.max(this.selectionStart.col, this.selectionEnd.col);
647
+ const selectRowMin = Math.min(this.selectionStart.row, this.selectionEnd.row);
648
+ const selectRowMax = Math.max(this.selectionStart.row, this.selectionEnd.row);
649
+ const selectVisible = selectColMin !== selectColMax || selectRowMin !== selectRowMax;
650
+ return html2`<div
651
+ role="none"
652
+ class="dx-grid"
653
+ data-grid=${this.gridId}
654
+ data-grid-mode=${this.mode}
655
+ ?data-grid-select=${selectVisible}
656
+ >
657
+ <div role="none" class="dx-grid__corner"></div>
658
+ <div role="none" class="dx-grid__columnheader">
659
+ <div
660
+ role="none"
661
+ class="dx-grid__columnheader__content"
662
+ style="transform:translate3d(${offsetInline}px,0,0);grid-template-columns:${this.templateColumns};"
663
+ >
664
+ ${[
665
+ ...Array(visibleCols)
666
+ ].map((_, c0) => {
667
+ const c = this.visColMin + c0;
668
+ return html2`<div
669
+ role="columnheader"
670
+ ?inert=${c < 0}
671
+ style="block-size:${this.rowDefault.size}px;grid-column:${c0 + 1}/${c0 + 2};"
672
+ >
673
+ <span id=${localChId(c0)}>${colToA1Notation(c)}</span>
674
+ ${(this.columns[c]?.resizeable ?? this.columnDefault.resizeable) && html2`<dx-grid-axis-resize-handle
675
+ axis="col"
676
+ index=${c}
677
+ size=${this.colSize(c)}
678
+ @dxaxisresizeinternal=${this.handleAxisResizeInternal}
679
+ ></dx-grid-axis-resize-handle>`}
680
+ </div>`;
681
+ })}
682
+ </div>
683
+ </div>
684
+ <div role="none" class="dx-grid__corner"></div>
685
+ <div role="none" class="dx-grid__rowheader">
686
+ <div
687
+ role="none"
688
+ class="dx-grid__rowheader__content"
689
+ style="transform:translate3d(0,${offsetBlock}px,0);grid-template-rows:${this.templateRows};"
690
+ >
691
+ ${[
692
+ ...Array(visibleRows)
693
+ ].map((_, r0) => {
694
+ const r = this.visRowMin + r0;
695
+ return html2`<div role="rowheader" ?inert=${r < 0} style="grid-row:${r0 + 1}/${r0 + 2}">
696
+ <span id=${localRhId(r0)}>${rowToA1Notation(r)}</span>
697
+ ${(this.rows[r]?.resizeable ?? this.rowDefault.resizeable) && html2`<dx-grid-axis-resize-handle
698
+ axis="row"
699
+ index=${r}
700
+ size=${this.rowSize(r)}
701
+ ></dx-grid-axis-resize-handle>`}
702
+ </div>`;
703
+ })}
704
+ </div>
705
+ </div>
706
+ <div role="grid" class="dx-grid__viewport" tabindex="0" @wheel=${this.handleWheel} ${ref2(this.viewportRef)}>
707
+ <div
708
+ role="none"
709
+ class="dx-grid__content"
710
+ style="transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this.templateColumns};grid-template-rows:${this.templateRows};"
711
+ >
712
+ ${[
713
+ ...Array(visibleCols)
714
+ ].map((_, c0) => {
715
+ return [
716
+ ...Array(visibleRows)
717
+ ].map((_2, r0) => {
718
+ const c = c0 + this.visColMin;
719
+ const r = r0 + this.visRowMin;
720
+ const cell = this.cell(c, r);
721
+ const active = this.focusActive && this.focusedCell.col === c && this.focusedCell.row === r;
722
+ const selected = c >= selectColMin && c <= selectColMax && r >= selectRowMin && r <= selectRowMax;
723
+ return html2`<div
724
+ role="gridcell"
725
+ tabindex="0"
726
+ ?inert=${c < 0 || r < 0}
727
+ ?aria-selected=${selected}
728
+ class=${cell || active ? (cell?.className ? cell.className + " " : "") + (active ? "dx-grid__cell--active" : "") : nothing}
729
+ aria-rowindex=${r}
730
+ aria-colindex=${c}
731
+ data-dx-grid-action="cell"
732
+ style="grid-column:${c0 + 1};grid-row:${r0 + 1}"
733
+ >
734
+ ${cell?.value}
735
+ </div>`;
736
+ });
737
+ })}
738
+ </div>
739
+ </div>
740
+ <div role="none" class="dx-grid__scrollbar" aria-orientation="vertical">
741
+ <div role="none" class="dx-grid__scrollbar__thumb"></div>
742
+ </div>
743
+ <div role="none" class="dx-grid__corner"></div>
744
+ <div role="none" class="dx-grid__scrollbar" aria-orientation="horizontal">
745
+ <div role="none" class="dx-grid__scrollbar__thumb"></div>
746
+ </div>
747
+ <div role="none" class="dx-grid__corner"></div>
748
+ </div>`;
749
+ }
750
+ firstUpdated() {
751
+ if (this.getCells) {
752
+ this.cells = this.getCells({
753
+ start: {
754
+ col: this.visColMin,
755
+ row: this.visRowMin
756
+ },
757
+ end: {
758
+ col: this.visColMax,
759
+ row: this.visRowMax
760
+ }
761
+ });
762
+ }
763
+ this.observer.observe(this.viewportRef.value);
764
+ this.colSizes = Object.entries(this.columns).reduce((acc, [colId, colMeta]) => {
765
+ if (colMeta?.size) {
766
+ acc[colId] = colMeta.size;
767
+ }
768
+ return acc;
769
+ }, {});
770
+ this.rowSizes = Object.entries(this.rows).reduce((acc, [rowId, rowMeta]) => {
771
+ if (rowMeta?.size) {
772
+ acc[rowId] = rowMeta.size;
773
+ }
774
+ return acc;
775
+ }, {});
776
+ }
777
+ willUpdate(changedProperties) {
778
+ if (this.getCells && (changedProperties.has("initialCells") || changedProperties.has("visColMin") || changedProperties.has("visColMax") || changedProperties.has("visRowMin") || changedProperties.has("visRowMax"))) {
779
+ this.cells = this.getCells({
780
+ start: {
781
+ col: this.visColMin,
782
+ row: this.visRowMin
783
+ },
784
+ end: {
785
+ col: this.visColMax,
786
+ row: this.visRowMax
787
+ }
788
+ });
789
+ }
790
+ }
791
+ updated(changedProperties) {
792
+ if (this.focusActive && (changedProperties.has("visRowMin") || changedProperties.has("visColMin") || changedProperties.has("focusedCell"))) {
793
+ this.refocus();
794
+ }
795
+ }
796
+ disconnectedCallback() {
797
+ super.disconnectedCallback();
798
+ if (this.viewportRef.value) {
799
+ this.observer.unobserve(this.viewportRef.value);
800
+ }
801
+ }
802
+ createRenderRoot() {
803
+ return this;
804
+ }
805
+ };
806
+ _ts_decorate2([
807
+ property2({
808
+ type: String
809
+ })
810
+ ], DxGrid.prototype, "gridId", void 0);
811
+ _ts_decorate2([
812
+ property2({
813
+ type: Object
814
+ })
815
+ ], DxGrid.prototype, "rowDefault", void 0);
816
+ _ts_decorate2([
817
+ property2({
818
+ type: Object
819
+ })
820
+ ], DxGrid.prototype, "columnDefault", void 0);
821
+ _ts_decorate2([
822
+ property2({
823
+ type: Object
824
+ })
825
+ ], DxGrid.prototype, "rows", void 0);
826
+ _ts_decorate2([
827
+ property2({
828
+ type: Object
829
+ })
830
+ ], DxGrid.prototype, "columns", void 0);
831
+ _ts_decorate2([
832
+ property2({
833
+ type: Object
834
+ })
835
+ ], DxGrid.prototype, "initialCells", void 0);
836
+ _ts_decorate2([
837
+ property2({
838
+ type: String
839
+ })
840
+ ], DxGrid.prototype, "mode", void 0);
841
+ _ts_decorate2([
842
+ state()
843
+ ], DxGrid.prototype, "cells", void 0);
844
+ _ts_decorate2([
845
+ state()
846
+ ], DxGrid.prototype, "posInline", void 0);
847
+ _ts_decorate2([
848
+ state()
849
+ ], DxGrid.prototype, "posBlock", void 0);
850
+ _ts_decorate2([
851
+ state()
852
+ ], DxGrid.prototype, "sizeInline", void 0);
853
+ _ts_decorate2([
854
+ state()
855
+ ], DxGrid.prototype, "sizeBlock", void 0);
856
+ _ts_decorate2([
857
+ state()
858
+ ], DxGrid.prototype, "overscanInline", void 0);
859
+ _ts_decorate2([
860
+ state()
861
+ ], DxGrid.prototype, "overscanBlock", void 0);
862
+ _ts_decorate2([
863
+ state()
864
+ ], DxGrid.prototype, "binInlineMin", void 0);
865
+ _ts_decorate2([
866
+ state()
867
+ ], DxGrid.prototype, "binInlineMax", void 0);
868
+ _ts_decorate2([
869
+ state()
870
+ ], DxGrid.prototype, "binBlockMin", void 0);
871
+ _ts_decorate2([
872
+ state()
873
+ ], DxGrid.prototype, "binBlockMax", void 0);
874
+ _ts_decorate2([
875
+ state()
876
+ ], DxGrid.prototype, "visColMin", void 0);
877
+ _ts_decorate2([
878
+ state()
879
+ ], DxGrid.prototype, "visColMax", void 0);
880
+ _ts_decorate2([
881
+ state()
882
+ ], DxGrid.prototype, "visRowMin", void 0);
883
+ _ts_decorate2([
884
+ state()
885
+ ], DxGrid.prototype, "visRowMax", void 0);
886
+ _ts_decorate2([
887
+ state()
888
+ ], DxGrid.prototype, "templateColumns", void 0);
889
+ _ts_decorate2([
890
+ state()
891
+ ], DxGrid.prototype, "templateRows", void 0);
892
+ _ts_decorate2([
893
+ state()
894
+ ], DxGrid.prototype, "pointer", void 0);
895
+ _ts_decorate2([
896
+ state()
897
+ ], DxGrid.prototype, "colSizes", void 0);
898
+ _ts_decorate2([
899
+ state()
900
+ ], DxGrid.prototype, "rowSizes", void 0);
901
+ _ts_decorate2([
902
+ state()
903
+ ], DxGrid.prototype, "focusActive", void 0);
904
+ _ts_decorate2([
905
+ state()
906
+ ], DxGrid.prototype, "focusedCell", void 0);
907
+ _ts_decorate2([
908
+ state()
909
+ ], DxGrid.prototype, "selectionStart", void 0);
910
+ _ts_decorate2([
911
+ state()
912
+ ], DxGrid.prototype, "selectionEnd", void 0);
913
+ _ts_decorate2([
914
+ state()
915
+ ], DxGrid.prototype, "observer", void 0);
916
+ _ts_decorate2([
917
+ eventOptions({
918
+ capture: true
919
+ })
920
+ ], DxGrid.prototype, "handleFocus", null);
921
+ _ts_decorate2([
922
+ eventOptions({
923
+ capture: true
924
+ })
925
+ ], DxGrid.prototype, "handleBlur", null);
926
+ DxGrid = _ts_decorate2([
927
+ customElement2("dx-grid")
928
+ ], DxGrid);
929
+ export {
930
+ DxAxisResize,
931
+ DxAxisResizeInternal,
932
+ DxEditRequest,
933
+ DxGrid,
934
+ DxGridCellsSelect
935
+ };
936
+ //# sourceMappingURL=index.mjs.map