@dxos/lit-grid 0.6.10 → 0.6.11-staging.32b42e4
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/lib/browser/index.mjs +171 -22
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/dx-grid.d.ts +18 -6
- package/dist/types/src/dx-grid.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +2 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +9 -0
- package/dist/types/src/types.d.ts.map +1 -0
- package/package.json +6 -3
- package/src/dx-grid.pcss +27 -7
- package/src/dx-grid.ts +170 -21
- package/src/index.ts +2 -1
- package/src/types.ts +19 -0
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
// packages/ui/lit-grid/src/dx-grid.ts
|
|
2
2
|
import { LitElement, html } from "lit";
|
|
3
|
-
import { customElement, state, property } from "lit/decorators.js";
|
|
3
|
+
import { customElement, state, property, eventOptions } from "lit/decorators.js";
|
|
4
4
|
import { ref, createRef } from "lit/directives/ref.js";
|
|
5
|
+
|
|
6
|
+
// packages/ui/lit-grid/src/types.ts
|
|
7
|
+
var DxAxisResize = class extends Event {
|
|
8
|
+
constructor(props) {
|
|
9
|
+
super("dx-axis-resize");
|
|
10
|
+
this.axis = props.axis;
|
|
11
|
+
this.index = props.index;
|
|
12
|
+
this.size = props.size;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// packages/ui/lit-grid/src/dx-grid.ts
|
|
5
17
|
function _ts_decorate(decorators, target, key, desc) {
|
|
6
18
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
7
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
8
|
-
|
|
9
|
-
else
|
|
10
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
11
|
-
if (d = decorators[i])
|
|
12
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
19
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
20
|
+
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;
|
|
13
21
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
14
22
|
}
|
|
15
23
|
var gap = 1;
|
|
@@ -100,7 +108,15 @@ var DxGrid = class extends LitElement {
|
|
|
100
108
|
}
|
|
101
109
|
};
|
|
102
110
|
this.handlePointerUp = (_event) => {
|
|
103
|
-
this.resizing
|
|
111
|
+
if (this.resizing) {
|
|
112
|
+
const resizeEvent = new DxAxisResize({
|
|
113
|
+
axis: this.resizing.axis,
|
|
114
|
+
index: this.resizing.index,
|
|
115
|
+
size: this[this.resizing.axis === "col" ? "colSize" : "rowSize"](this.resizing.index)
|
|
116
|
+
});
|
|
117
|
+
this.dispatchEvent(resizeEvent);
|
|
118
|
+
this.resizing = null;
|
|
119
|
+
}
|
|
104
120
|
};
|
|
105
121
|
this.handlePointerMove = (event) => {
|
|
106
122
|
if (this.resizing) {
|
|
@@ -145,6 +161,12 @@ var DxGrid = class extends LitElement {
|
|
|
145
161
|
this.updateVis();
|
|
146
162
|
}
|
|
147
163
|
};
|
|
164
|
+
// Focus handlers
|
|
165
|
+
this.focusedCell = {
|
|
166
|
+
col: 0,
|
|
167
|
+
row: 0
|
|
168
|
+
};
|
|
169
|
+
this.focusActive = false;
|
|
148
170
|
}
|
|
149
171
|
//
|
|
150
172
|
// Accessors
|
|
@@ -174,11 +196,11 @@ var DxGrid = class extends LitElement {
|
|
|
174
196
|
acc += this.colSize(this.visColMin + c0);
|
|
175
197
|
return acc;
|
|
176
198
|
}, 0) + gap * (overscanCol - 1);
|
|
177
|
-
while (pxInline < this.binInlineMax + this.sizeInline) {
|
|
199
|
+
while (pxInline < this.binInlineMax + this.sizeInline + gap) {
|
|
178
200
|
colIndex += 1;
|
|
179
201
|
pxInline += this.colSize(colIndex) + gap;
|
|
180
202
|
}
|
|
181
|
-
this.visColMax = colIndex + overscanCol
|
|
203
|
+
this.visColMax = colIndex + overscanCol;
|
|
182
204
|
this.templateColumns = [
|
|
183
205
|
...Array(this.visColMax - this.visColMin)
|
|
184
206
|
].map((_, c0) => `${this.colSize(this.visColMin + c0)}px`).join(" ");
|
|
@@ -203,7 +225,7 @@ var DxGrid = class extends LitElement {
|
|
|
203
225
|
rowIndex += 1;
|
|
204
226
|
pxBlock += this.rowSize(rowIndex) + gap;
|
|
205
227
|
}
|
|
206
|
-
this.visRowMax = rowIndex + overscanRow
|
|
228
|
+
this.visRowMax = rowIndex + overscanRow;
|
|
207
229
|
this.templateRows = [
|
|
208
230
|
...Array(this.visRowMax - this.visRowMin)
|
|
209
231
|
].map((_, r0) => `${this.rowSize(this.visRowMin + r0)}px`).join(" ");
|
|
@@ -212,20 +234,124 @@ var DxGrid = class extends LitElement {
|
|
|
212
234
|
this.updateVisInline();
|
|
213
235
|
this.updateVisBlock();
|
|
214
236
|
}
|
|
237
|
+
handleFocus(event) {
|
|
238
|
+
const target = event.target;
|
|
239
|
+
const action = target.getAttribute("data-dx-grid-action");
|
|
240
|
+
if (action === "cell") {
|
|
241
|
+
const c = parseInt(target.getAttribute("aria-colindex") ?? "never");
|
|
242
|
+
const r = parseInt(target.getAttribute("aria-rowindex") ?? "never");
|
|
243
|
+
this.focusedCell = {
|
|
244
|
+
col: c,
|
|
245
|
+
row: r
|
|
246
|
+
};
|
|
247
|
+
this.focusActive = true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
handleBlur(event) {
|
|
251
|
+
if (!event.relatedTarget || event.relatedTarget.closest(".dx-grid__viewport") !== this.viewportRef.value) {
|
|
252
|
+
this.focusActive = false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Moves focus to the cell with actual focus, otherwise moves focus to the viewport.
|
|
257
|
+
*/
|
|
258
|
+
refocus() {
|
|
259
|
+
(this.focusedCell.row < this.visRowMin || this.focusedCell.row > this.visRowMax || this.focusedCell.col < this.visColMin || this.focusedCell.col > this.visColMax ? this.viewportRef.value : this.viewportRef.value?.querySelector(`[aria-colindex="${this.focusedCell.col}"][aria-rowindex="${this.focusedCell.row}"]`))?.focus({
|
|
260
|
+
preventScroll: true
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Updates `pos` so that a cell in focus is fully within the viewport
|
|
265
|
+
*/
|
|
266
|
+
snapPosToFocusedCell() {
|
|
267
|
+
if (this.focusedCell.col < this.visColMin || this.focusedCell.col > this.visColMax || this.focusedCell.row < this.visRowMin || this.focusedCell.row > this.visRowMax) {
|
|
268
|
+
} 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) {
|
|
269
|
+
} else {
|
|
270
|
+
if (this.focusedCell.col <= this.visColMin + overscanCol) {
|
|
271
|
+
this.posInline = this.binInlineMin;
|
|
272
|
+
this.updateVisInline();
|
|
273
|
+
} else if (this.focusedCell.col >= this.visColMax - overscanCol - 1) {
|
|
274
|
+
const sizeSumCol = [
|
|
275
|
+
...Array(this.focusedCell.col - this.visColMin)
|
|
276
|
+
].reduce((acc, _, c0) => {
|
|
277
|
+
acc += this.colSize(this.visColMin + overscanCol + c0) + gap;
|
|
278
|
+
return acc;
|
|
279
|
+
}, 0);
|
|
280
|
+
this.posInline = this.binInlineMin + sizeSumCol + gap * 2 - this.sizeInline;
|
|
281
|
+
this.updateVisInline();
|
|
282
|
+
}
|
|
283
|
+
if (this.focusedCell.row <= this.visRowMin + overscanRow) {
|
|
284
|
+
this.posBlock = this.binBlockMin;
|
|
285
|
+
this.updateVisBlock();
|
|
286
|
+
} else if (this.focusedCell.row >= this.visRowMax - overscanRow - 1) {
|
|
287
|
+
const sizeSumRow = [
|
|
288
|
+
...Array(this.focusedCell.row - this.visRowMin)
|
|
289
|
+
].reduce((acc, _, r0) => {
|
|
290
|
+
acc += this.rowSize(this.visRowMin + overscanRow + r0) + gap;
|
|
291
|
+
return acc;
|
|
292
|
+
}, 0);
|
|
293
|
+
this.posBlock = this.binBlockMin + sizeSumRow + gap * 2 - this.sizeBlock;
|
|
294
|
+
this.updateVisBlock();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Keyboard interactions
|
|
299
|
+
handleKeydown(event) {
|
|
300
|
+
if (this.focusActive) {
|
|
301
|
+
switch (event.key) {
|
|
302
|
+
case "ArrowDown":
|
|
303
|
+
this.focusedCell = {
|
|
304
|
+
...this.focusedCell,
|
|
305
|
+
row: this.focusedCell.row + 1
|
|
306
|
+
};
|
|
307
|
+
break;
|
|
308
|
+
case "ArrowUp":
|
|
309
|
+
this.focusedCell = {
|
|
310
|
+
...this.focusedCell,
|
|
311
|
+
row: Math.max(0, this.focusedCell.row - 1)
|
|
312
|
+
};
|
|
313
|
+
break;
|
|
314
|
+
case "ArrowRight":
|
|
315
|
+
this.focusedCell = {
|
|
316
|
+
...this.focusedCell,
|
|
317
|
+
col: this.focusedCell.col + 1
|
|
318
|
+
};
|
|
319
|
+
break;
|
|
320
|
+
case "ArrowLeft":
|
|
321
|
+
this.focusedCell = {
|
|
322
|
+
...this.focusedCell,
|
|
323
|
+
col: Math.max(0, this.focusedCell.col - 1)
|
|
324
|
+
};
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
switch (event.key) {
|
|
328
|
+
case "ArrowDown":
|
|
329
|
+
case "ArrowUp":
|
|
330
|
+
case "ArrowRight":
|
|
331
|
+
case "ArrowLeft":
|
|
332
|
+
event.preventDefault();
|
|
333
|
+
this.snapPosToFocusedCell();
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
215
338
|
//
|
|
216
339
|
// Render and other lifecycle methods
|
|
217
340
|
//
|
|
218
341
|
render() {
|
|
219
342
|
const visibleCols = this.visColMax - this.visColMin;
|
|
220
343
|
const visibleRows = this.visRowMax - this.visRowMin;
|
|
221
|
-
const offsetInline = this.binInlineMin - this.posInline - this.overscanInline;
|
|
222
|
-
const offsetBlock = this.binBlockMin - this.posBlock - this.overscanBlock;
|
|
344
|
+
const offsetInline = gap + this.binInlineMin - this.posInline - this.overscanInline;
|
|
345
|
+
const offsetBlock = gap + this.binBlockMin - this.posBlock - this.overscanBlock;
|
|
223
346
|
return html`<div
|
|
224
347
|
role="none"
|
|
225
348
|
class="dx-grid"
|
|
226
349
|
@pointerdown=${this.handlePointerDown}
|
|
227
350
|
@pointerup=${this.handlePointerUp}
|
|
228
351
|
@pointermove=${this.handlePointerMove}
|
|
352
|
+
@focus=${this.handleFocus}
|
|
353
|
+
@blur=${this.handleBlur}
|
|
354
|
+
@keydown=${this.handleKeydown}
|
|
229
355
|
>
|
|
230
356
|
<div role="none" class="dx-grid__corner"></div>
|
|
231
357
|
<div role="none" class="dx-grid__columnheader">
|
|
@@ -241,7 +367,7 @@ var DxGrid = class extends LitElement {
|
|
|
241
367
|
return html`<div
|
|
242
368
|
role="columnheader"
|
|
243
369
|
?inert=${c < 0}
|
|
244
|
-
style="
|
|
370
|
+
style="block-size:${this.rowDefault.size}px;grid-column:${c0 + 1}/${c0 + 2};"
|
|
245
371
|
>
|
|
246
372
|
<span id=${localChId(c0)}>${colToA1Notation(c)}</span>
|
|
247
373
|
${(this.columns[c]?.resizeable ?? this.columnDefault.resizeable) && html`<button class="dx-grid__resize-handle" data-dx-grid-action=${`resize-col,${c}`}>
|
|
@@ -253,16 +379,16 @@ var DxGrid = class extends LitElement {
|
|
|
253
379
|
</div>
|
|
254
380
|
<div role="none" class="dx-grid__corner"></div>
|
|
255
381
|
<div role="none" class="dx-grid__rowheader">
|
|
256
|
-
<div
|
|
382
|
+
<div
|
|
383
|
+
role="none"
|
|
384
|
+
class="dx-grid__rowheader__content"
|
|
385
|
+
style="transform:translate3d(0,${offsetBlock}px,0);grid-template-rows:${this.templateRows};"
|
|
386
|
+
>
|
|
257
387
|
${[
|
|
258
388
|
...Array(visibleRows)
|
|
259
389
|
].map((_, r0) => {
|
|
260
390
|
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
|
-
>
|
|
391
|
+
return html`<div role="rowheader" ?inert=${r < 0} style="grid-row:${r0 + 1}/${r0 + 2}">
|
|
266
392
|
<span id=${localRhId(r0)}>${rowToA1Notation(r)}</span>
|
|
267
393
|
${(this.rows[r]?.resizeable ?? this.rowDefault.resizeable) && html`<button class="dx-grid__resize-handle" data-dx-grid-action=${`resize-row,${r}`}>
|
|
268
394
|
<span class="sr-only">Resize</span>
|
|
@@ -271,9 +397,9 @@ var DxGrid = class extends LitElement {
|
|
|
271
397
|
})}
|
|
272
398
|
</div>
|
|
273
399
|
</div>
|
|
274
|
-
<div role="
|
|
400
|
+
<div role="grid" class="dx-grid__viewport" tabindex="0" @wheel=${this.handleWheel} ${ref(this.viewportRef)}>
|
|
275
401
|
<div
|
|
276
|
-
role="
|
|
402
|
+
role="none"
|
|
277
403
|
class="dx-grid__content"
|
|
278
404
|
style="transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this.templateColumns};grid-template-rows:${this.templateRows};"
|
|
279
405
|
>
|
|
@@ -288,6 +414,7 @@ var DxGrid = class extends LitElement {
|
|
|
288
414
|
const cell = this.getCell(c, r);
|
|
289
415
|
return html`<div
|
|
290
416
|
role="gridcell"
|
|
417
|
+
tabindex="0"
|
|
291
418
|
?inert=${c < 0 || r < 0}
|
|
292
419
|
aria-rowindex=${r}
|
|
293
420
|
aria-colindex=${c}
|
|
@@ -325,6 +452,11 @@ var DxGrid = class extends LitElement {
|
|
|
325
452
|
return acc;
|
|
326
453
|
}, {});
|
|
327
454
|
}
|
|
455
|
+
updated(changedProperties) {
|
|
456
|
+
if (this.focusActive && (changedProperties.has("visRowMin") || changedProperties.has("visColMin") || changedProperties.has("focusedCell"))) {
|
|
457
|
+
this.refocus();
|
|
458
|
+
}
|
|
459
|
+
}
|
|
328
460
|
disconnectedCallback() {
|
|
329
461
|
super.disconnectedCallback();
|
|
330
462
|
if (this.viewportRef.value) {
|
|
@@ -420,10 +552,27 @@ _ts_decorate([
|
|
|
420
552
|
_ts_decorate([
|
|
421
553
|
state()
|
|
422
554
|
], DxGrid.prototype, "observer", void 0);
|
|
555
|
+
_ts_decorate([
|
|
556
|
+
state()
|
|
557
|
+
], DxGrid.prototype, "focusedCell", void 0);
|
|
558
|
+
_ts_decorate([
|
|
559
|
+
state()
|
|
560
|
+
], DxGrid.prototype, "focusActive", void 0);
|
|
561
|
+
_ts_decorate([
|
|
562
|
+
eventOptions({
|
|
563
|
+
capture: true
|
|
564
|
+
})
|
|
565
|
+
], DxGrid.prototype, "handleFocus", null);
|
|
566
|
+
_ts_decorate([
|
|
567
|
+
eventOptions({
|
|
568
|
+
capture: true
|
|
569
|
+
})
|
|
570
|
+
], DxGrid.prototype, "handleBlur", null);
|
|
423
571
|
DxGrid = _ts_decorate([
|
|
424
572
|
customElement("dx-grid")
|
|
425
573
|
], DxGrid);
|
|
426
574
|
export {
|
|
575
|
+
DxAxisResize,
|
|
427
576
|
DxGrid
|
|
428
577
|
};
|
|
429
578
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/dx-grid.ts"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { LitElement, html } from 'lit';\nimport { customElement, state, property } from 'lit/decorators.js';\nimport { ref, createRef, type Ref } from 'lit/directives/ref.js';\n\n/**\n * The size in pixels of the gap between cells\n */\nconst gap = 1;\n\n/**\n * This should be about the width of the `1` numeral so resize is triggered as the row header column’s intrinsic size\n * changes when scrolling vertically.\n */\nconst resizeTolerance = 8;\n\n//\n// `overscan` is the number of columns or rows to render outside of the viewport\n//\nconst overscanCol = 1;\nconst overscanRow = 1;\n\n//\n// `size`, when suffixed with ‘row’ or ‘col’, are limits on size applied when resizing\n//\nconst sizeColMin = 32;\nconst sizeColMax = 1024;\nconst sizeRowMin = 16;\nconst sizeRowMax = 1024;\n\n/**\n * Separator for serializing cell position vectors\n */\nconst separator = ',';\n\n//\n// A1 notation is the fallback for numbering columns and rows.\n//\n\nconst colToA1Notation = (col: number): string => {\n return (\n (col >= 26 ? String.fromCharCode('A'.charCodeAt(0) + Math.floor(col / 26) - 1) : '') +\n String.fromCharCode('A'.charCodeAt(0) + (col % 26))\n );\n};\n\nconst rowToA1Notation = (row: number): string => {\n return `${row + 1}`;\n};\n\nexport type CellValue = {\n /**\n * The content value\n */\n value: string;\n /**\n * If this is a merged cell, the bottomright-most of the range in numeric notation, otherwise undefined.\n */\n end?: string;\n /**\n * CSS inline styles to apply to the gridcell element\n */\n style?: string;\n};\n\ntype AxisMeta = {\n size: number;\n description?: string;\n resizeable?: boolean;\n};\n\nexport type DxGridProps = Pick<DxGrid, 'cells' | 'rows' | 'columns' | 'rowDefault' | 'columnDefault'>;\n\nconst localChId = (c0: number) => `ch--${c0}`;\nconst localRhId = (r0: number) => `rh--${r0}`;\n\nconst getPage = (axis: string, event: PointerEvent) => (axis === 'col' ? event.pageX : event.pageY);\n\n@customElement('dx-grid')\nexport class DxGrid extends LitElement {\n @property({ type: Object })\n rowDefault: AxisMeta = { size: 32 };\n\n @property({ type: Object })\n columnDefault: AxisMeta = { size: 180 };\n\n @property({ type: Object })\n rows: Record<string, AxisMeta> = {};\n\n @property({ type: Object })\n columns: Record<string, AxisMeta> = {};\n\n @property({ type: Object })\n cells: Record<string, CellValue> = {};\n\n //\n // `pos`, short for ‘position’, is the position in pixels of the viewport from the origin.\n //\n\n @state()\n posInline = 0;\n\n @state()\n posBlock = 0;\n\n //\n // `size` (when not suffixed with ‘row’ or ‘col’, see above) is the size in pixels of the viewport.\n //\n\n @state()\n sizeInline = 0;\n\n @state()\n sizeBlock = 0;\n\n //\n // `overscan` is the amount in pixels to offset the grid content due to the number of overscanned columns or rows.\n //\n\n @state()\n overscanInline = 0;\n\n @state()\n overscanBlock = 0;\n\n //\n // `bin`, not short for anything, is the range in pixels within which virtualization does not need to reassess.\n //\n\n @state()\n binInlineMin = 0;\n\n @state()\n binInlineMax = this.colSize(0);\n\n @state()\n binBlockMin = 0;\n\n @state()\n binBlockMax = this.rowSize(0);\n\n //\n // `vis`, short for ‘visible’, is the range in numeric index of the columns or rows which should be rendered within\n // the viewport. These start with naïve values that are updated before first contentful render.\n //\n\n @state()\n visColMin = 0;\n\n @state()\n visColMax = 1;\n\n @state()\n visRowMin = 0;\n\n @state()\n visRowMax = 1;\n\n //\n // `template` is the rendered value of `grid-{axis}-template`.\n //\n @state()\n templateColumns = `${this.colSize(0)}px`;\n\n @state()\n templateRows = `${this.rowSize(0)}px`;\n\n //\n // Resize state and handlers\n //\n\n @state()\n colSizes: Record<string, number> = {};\n\n @state()\n rowSizes: Record<string, number> = {};\n\n @state()\n resizing: null | { axis: 'col' | 'row'; page: number; size: number; index: string } = null;\n\n handlePointerDown = (event: PointerEvent) => {\n const actionEl = (event.target as HTMLElement)?.closest('[data-dx-grid-action]');\n const action = actionEl?.getAttribute('data-dx-grid-action');\n if (action) {\n if (action.startsWith('resize')) {\n const [resize, index] = action.split(',');\n const [_, axis] = resize.split('-');\n this.resizing = {\n axis: axis as 'col' | 'row',\n size: axis === 'col' ? this.colSize(index) : this.rowSize(index),\n page: getPage(axis, event),\n index,\n };\n }\n }\n };\n\n handlePointerUp = (_event: PointerEvent) => {\n this.resizing = null;\n };\n\n handlePointerMove = (event: PointerEvent) => {\n if (this.resizing) {\n const delta = getPage(this.resizing.axis, event) - this.resizing.page;\n if (this.resizing.axis === 'col') {\n const nextSize = Math.max(sizeColMin, Math.min(sizeColMax, this.resizing.size + delta));\n this.colSizes = { ...this.colSizes, [this.resizing.index]: nextSize };\n this.updateVisInline();\n } else {\n const nextSize = Math.max(sizeRowMin, Math.min(sizeRowMax, this.resizing.size + delta));\n this.rowSizes = { ...this.rowSizes, [this.resizing.index]: nextSize };\n this.updateVisBlock();\n }\n }\n };\n\n //\n // Accessors\n //\n\n private colSize(c: number | string) {\n return this.colSizes?.[c] ?? this.columnDefault.size;\n }\n\n private rowSize(r: number | string) {\n return this.rowSizes?.[r] ?? this.rowDefault.size;\n }\n\n private getCell(c: number | string, r: number | string) {\n return this.cells[`${c}${separator}${r}`];\n }\n\n //\n // Resize & reposition handlers, observer, ref\n //\n\n @state()\n observer = new ResizeObserver((entries) => {\n const { inlineSize, blockSize } = entries?.[0]?.contentBoxSize?.[0] ?? {\n inlineSize: 0,\n blockSize: 0,\n };\n if (\n Math.abs(inlineSize - this.sizeInline) > resizeTolerance ||\n Math.abs(blockSize - this.sizeBlock) > resizeTolerance\n ) {\n // console.info('[updating bounds]', 'resize', [inlineSize - this.sizeInline, blockSize - this.sizeBlock]);\n this.sizeInline = inlineSize;\n this.sizeBlock = blockSize;\n this.updateVis();\n }\n });\n\n viewportRef: Ref<HTMLDivElement> = createRef();\n\n handleWheel = ({ deltaX, deltaY }: WheelEvent) => {\n this.posInline = Math.max(0, this.posInline + deltaX);\n this.posBlock = Math.max(0, this.posBlock + deltaY);\n if (\n this.posInline >= this.binInlineMin &&\n this.posInline < this.binInlineMax &&\n this.posBlock >= this.binBlockMin &&\n this.posBlock < this.binBlockMax\n ) {\n // do nothing\n } else {\n // console.info(\n // '[updating bounds]',\n // 'wheel',\n // [this.binInlineMin, this.posInline, this.binInlineMax],\n // [this.binBlockMin, this.posBlock, this.binBlockMax],\n // );\n this.updateVis();\n }\n };\n\n private updateVisInline() {\n // todo: avoid starting from zero\n let colIndex = 0;\n let pxInline = this.colSize(colIndex);\n\n while (pxInline < this.posInline) {\n colIndex += 1;\n pxInline += this.colSize(colIndex) + gap;\n }\n\n this.visColMin = colIndex - overscanCol;\n\n this.binInlineMin = pxInline - this.colSize(colIndex) - gap;\n this.binInlineMax = pxInline + gap;\n\n this.overscanInline =\n [...Array(overscanCol)].reduce((acc, _, c0) => {\n acc += this.colSize(this.visColMin + c0);\n return acc;\n }, 0) +\n gap * (overscanCol - 1);\n\n while (pxInline < this.binInlineMax + this.sizeInline) {\n colIndex += 1;\n pxInline += this.colSize(colIndex) + gap;\n }\n\n this.visColMax = colIndex + overscanCol + 1;\n\n this.templateColumns = [...Array(this.visColMax - this.visColMin)]\n .map((_, c0) => `${this.colSize(this.visColMin + c0)}px`)\n .join(' ');\n }\n\n private updateVisBlock() {\n // todo: avoid starting from zero\n let rowIndex = 0;\n let pxBlock = this.rowSize(rowIndex);\n\n while (pxBlock < this.posBlock) {\n rowIndex += 1;\n pxBlock += this.rowSize(rowIndex) + gap;\n }\n\n this.visRowMin = rowIndex - overscanRow;\n\n this.binBlockMin = pxBlock - this.rowSize(rowIndex) - gap;\n this.binBlockMax = pxBlock + gap;\n\n this.overscanBlock =\n [...Array(overscanRow)].reduce((acc, _, r0) => {\n acc += this.rowSize(this.visRowMin + r0);\n return acc;\n }, 0) +\n gap * (overscanRow - 1);\n\n while (pxBlock < this.binBlockMax + this.sizeBlock) {\n rowIndex += 1;\n pxBlock += this.rowSize(rowIndex) + gap;\n }\n\n this.visRowMax = rowIndex + overscanRow + 1;\n\n this.templateRows = [...Array(this.visRowMax - this.visRowMin)]\n .map((_, r0) => `${this.rowSize(this.visRowMin + r0)}px`)\n .join(' ');\n }\n\n private updateVis() {\n this.updateVisInline();\n this.updateVisBlock();\n }\n\n //\n // Render and other lifecycle methods\n //\n\n override render() {\n const visibleCols = this.visColMax - this.visColMin;\n const visibleRows = this.visRowMax - this.visRowMin;\n // TODO NEXT -> ensure offset is using the right components\n const offsetInline = this.binInlineMin - this.posInline - this.overscanInline;\n const offsetBlock = this.binBlockMin - this.posBlock - this.overscanBlock;\n\n return html`<div\n role=\"none\"\n class=\"dx-grid\"\n @pointerdown=${this.handlePointerDown}\n @pointerup=${this.handlePointerUp}\n @pointermove=${this.handlePointerMove}\n >\n <div role=\"none\" class=\"dx-grid__corner\"></div>\n <div role=\"none\" class=\"dx-grid__columnheader\">\n <div\n role=\"none\"\n class=\"dx-grid__columnheader__content\"\n style=\"transform:translate3d(${offsetInline}px,0,0);grid-template-columns:${this.templateColumns};\"\n >\n ${[...Array(visibleCols)].map((_, c0) => {\n const c = this.visColMin + c0;\n return html`<div\n role=\"columnheader\"\n ?inert=${c < 0}\n style=\"inline-size:${this.colSize(c)}px;block-size:${this.rowDefault.size}px;grid-column:${c0 + 1}/${c0 +\n 2};\"\n >\n <span id=${localChId(c0)}>${colToA1Notation(c)}</span>\n ${(this.columns[c]?.resizeable ?? this.columnDefault.resizeable) &&\n html`<button class=\"dx-grid__resize-handle\" data-dx-grid-action=${`resize-col,${c}`}>\n <span class=\"sr-only\">Resize</span>\n </button>`}\n </div>`;\n })}\n </div>\n </div>\n <div role=\"none\" class=\"dx-grid__corner\"></div>\n <div role=\"none\" class=\"dx-grid__rowheader\">\n <div role=\"none\" class=\"dx-grid__rowheader__content\" style=\"transform:translate3d(0,${offsetBlock}px,0);\">\n ${[...Array(visibleRows)].map((_, r0) => {\n const r = this.visRowMin + r0;\n return html`<div\n role=\"rowheader\"\n ?inert=${r < 0}\n style=\"block-size:${this.rowSize(r)}px;grid-row:${r0 + 1}/${r0 + 2}\"\n >\n <span id=${localRhId(r0)}>${rowToA1Notation(r)}</span>\n ${(this.rows[r]?.resizeable ?? this.rowDefault.resizeable) &&\n html`<button class=\"dx-grid__resize-handle\" data-dx-grid-action=${`resize-row,${r}`}>\n <span class=\"sr-only\">Resize</span>\n </button>`}\n </div>`;\n })}\n </div>\n </div>\n <div role=\"none\" class=\"dx-grid__viewport\" @wheel=\"${this.handleWheel}\" ${ref(this.viewportRef)}>\n <div\n role=\"grid\"\n class=\"dx-grid__content\"\n style=\"transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this\n .templateColumns};grid-template-rows:${this.templateRows};\"\n >\n ${[...Array(visibleCols)].map((_, c0) => {\n return [...Array(visibleRows)].map((_, r0) => {\n const c = c0 + this.visColMin;\n const r = r0 + this.visRowMin;\n const cell = this.getCell(c, r);\n return html`<div\n role=\"gridcell\"\n ?inert=${c < 0 || r < 0}\n aria-rowindex=${r}\n aria-colindex=${c}\n data-dx-grid-action=\"cell\"\n style=\"grid-column:${c0 + 1};grid-row:${r0 + 1}\"\n >\n ${cell?.value}\n </div>`;\n });\n })}\n </div>\n </div>\n <div role=\"none\" class=\"dx-grid__scrollbar\" aria-orientation=\"vertical\">\n <div role=\"none\" class=\"dx-grid__scrollbar__thumb\"></div>\n </div>\n <div role=\"none\" class=\"dx-grid__corner\"></div>\n <div role=\"none\" class=\"dx-grid__scrollbar\" aria-orientation=\"horizontal\">\n <div role=\"none\" class=\"dx-grid__scrollbar__thumb\"></div>\n </div>\n <div role=\"none\" class=\"dx-grid__corner\"></div>\n </div>`;\n }\n\n override firstUpdated() {\n this.observer.observe(this.viewportRef.value!);\n this.colSizes = Object.entries(this.columns).reduce((acc: Record<string, number>, [colId, colMeta]) => {\n if (colMeta?.size) {\n acc[colId] = colMeta.size;\n }\n return acc;\n }, {});\n this.rowSizes = Object.entries(this.rows).reduce((acc: Record<string, number>, [rowId, rowMeta]) => {\n if (rowMeta?.size) {\n acc[rowId] = rowMeta.size;\n }\n return acc;\n }, {});\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n // console.log('[disconnected]', this.viewportRef.value);\n // TODO(thure): Will this even work?\n if (this.viewportRef.value) {\n this.observer.unobserve(this.viewportRef.value);\n }\n }\n\n override createRenderRoot() {\n return this;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["LitElement", "html", "customElement", "state", "property", "ref", "createRef", "gap", "resizeTolerance", "overscanCol", "overscanRow", "sizeColMin", "sizeColMax", "sizeRowMin", "sizeRowMax", "separator", "colToA1Notation", "col", "String", "fromCharCode", "charCodeAt", "Math", "floor", "rowToA1Notation", "row", "localChId", "c0", "localRhId", "r0", "getPage", "axis", "event", "pageX", "pageY", "DxGrid", "LitElement", "rowDefault", "size", "columnDefault", "rows", "columns", "cells", "posInline", "posBlock", "sizeInline", "sizeBlock", "overscanInline", "overscanBlock", "binInlineMin", "binInlineMax", "colSize", "binBlockMin", "binBlockMax", "rowSize", "visColMin", "visColMax", "visRowMin", "visRowMax", "templateColumns", "templateRows", "colSizes", "rowSizes", "resizing", "handlePointerDown", "actionEl", "target", "closest", "action", "getAttribute", "startsWith", "resize", "index", "split", "_", "page", "handlePointerUp", "_event", "handlePointerMove", "delta", "nextSize", "max", "min", "updateVisInline", "updateVisBlock", "observer", "ResizeObserver", "entries", "inlineSize", "blockSize", "contentBoxSize", "abs", "updateVis", "viewportRef", "createRef", "handleWheel", "deltaX", "deltaY", "c", "r", "getCell", "colIndex", "pxInline", "Array", "reduce", "acc", "map", "join", "rowIndex", "pxBlock", "render", "visibleCols", "visibleRows", "offsetInline", "offsetBlock", "html", "resizeable", "ref", "cell", "
|
|
3
|
+
"sources": ["../../../src/dx-grid.ts", "../../../src/types.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { LitElement, html } from 'lit';\nimport { customElement, state, property, eventOptions } from 'lit/decorators.js';\nimport { ref, createRef, type Ref } from 'lit/directives/ref.js';\n\nimport { DxAxisResize, type DxAxisResizeProps, type DxGridAxis } from './types';\n\n/**\n * The size in pixels of the gap between cells\n */\nconst gap = 1;\n\n/**\n * This should be about the width of the `1` numeral so resize is triggered as the row header column’s intrinsic size\n * changes when scrolling vertically.\n */\nconst resizeTolerance = 8;\n\n//\n// `overscan` is the number of columns or rows to render outside of the viewport\n//\nconst overscanCol = 1;\nconst overscanRow = 1;\n\n//\n// `size`, when suffixed with ‘row’ or ‘col’, are limits on size applied when resizing\n//\nconst sizeColMin = 32;\nconst sizeColMax = 1024;\nconst sizeRowMin = 16;\nconst sizeRowMax = 1024;\n\n/**\n * Separator for serializing cell position vectors\n */\nconst separator = ',';\n\n//\n// A1 notation is the fallback for numbering columns and rows.\n//\n\nconst colToA1Notation = (col: number): string => {\n return (\n (col >= 26 ? String.fromCharCode('A'.charCodeAt(0) + Math.floor(col / 26) - 1) : '') +\n String.fromCharCode('A'.charCodeAt(0) + (col % 26))\n );\n};\n\nconst rowToA1Notation = (row: number): string => {\n return `${row + 1}`;\n};\n\nexport type CellValue = {\n /**\n * The content value\n */\n value: string;\n /**\n * If this is a merged cell, the bottomright-most of the range in numeric notation, otherwise undefined.\n */\n end?: string;\n /**\n * CSS inline styles to apply to the gridcell element\n */\n style?: string;\n};\n\ntype AxisMeta = {\n size: number;\n description?: string;\n resizeable?: boolean;\n};\n\nexport type DxGridProps = Partial<Pick<DxGrid, 'cells' | 'rows' | 'columns' | 'rowDefault' | 'columnDefault'>>;\n\nconst localChId = (c0: number) => `ch--${c0}`;\nconst localRhId = (r0: number) => `rh--${r0}`;\n\nconst getPage = (axis: string, event: PointerEvent) => (axis === 'col' ? event.pageX : event.pageY);\n\n@customElement('dx-grid')\nexport class DxGrid extends LitElement {\n @property({ type: Object })\n rowDefault: AxisMeta = { size: 32 };\n\n @property({ type: Object })\n columnDefault: AxisMeta = { size: 180 };\n\n @property({ type: Object })\n rows: Record<string, AxisMeta> = {};\n\n @property({ type: Object })\n columns: Record<string, AxisMeta> = {};\n\n @property({ type: Object })\n cells: Record<string, CellValue> = {};\n\n //\n // `pos`, short for ‘position’, is the position in pixels of the viewport from the origin.\n //\n\n @state()\n posInline = 0;\n\n @state()\n posBlock = 0;\n\n //\n // `size` (when not suffixed with ‘row’ or ‘col’, see above) is the size in pixels of the viewport.\n //\n\n @state()\n sizeInline = 0;\n\n @state()\n sizeBlock = 0;\n\n //\n // `overscan` is the amount in pixels to offset the grid content due to the number of overscanned columns or rows.\n //\n\n @state()\n overscanInline = 0;\n\n @state()\n overscanBlock = 0;\n\n //\n // `bin`, not short for anything, is the range in pixels within which virtualization does not need to reassess.\n //\n\n @state()\n binInlineMin = 0;\n\n @state()\n binInlineMax = this.colSize(0);\n\n @state()\n binBlockMin = 0;\n\n @state()\n binBlockMax = this.rowSize(0);\n\n //\n // `vis`, short for ‘visible’, is the range in numeric index of the columns or rows which should be rendered within\n // the viewport. These start with naïve values that are updated before first contentful render.\n //\n\n @state()\n visColMin = 0;\n\n @state()\n visColMax = 1;\n\n @state()\n visRowMin = 0;\n\n @state()\n visRowMax = 1;\n\n //\n // `template` is the rendered value of `grid-{axis}-template`.\n //\n @state()\n templateColumns = `${this.colSize(0)}px`;\n\n @state()\n templateRows = `${this.rowSize(0)}px`;\n\n //\n // Resize state and handlers\n //\n\n @state()\n colSizes: Record<string, number> = {};\n\n @state()\n rowSizes: Record<string, number> = {};\n\n @state()\n resizing: null | (DxAxisResizeProps & { page: number }) = null;\n\n handlePointerDown = (event: PointerEvent) => {\n const actionEl = (event.target as HTMLElement)?.closest('[data-dx-grid-action]');\n const action = actionEl?.getAttribute('data-dx-grid-action');\n if (action) {\n if (action.startsWith('resize')) {\n const [resize, index] = action.split(',');\n const [_, axis] = resize.split('-');\n this.resizing = {\n axis: axis as DxGridAxis,\n size: axis === 'col' ? this.colSize(index) : this.rowSize(index),\n page: getPage(axis, event),\n index,\n };\n }\n }\n };\n\n handlePointerUp = (_event: PointerEvent) => {\n if (this.resizing) {\n const resizeEvent = new DxAxisResize({\n axis: this.resizing.axis,\n index: this.resizing.index,\n size: this[this.resizing.axis === 'col' ? 'colSize' : 'rowSize'](this.resizing.index),\n });\n this.dispatchEvent(resizeEvent);\n this.resizing = null;\n }\n };\n\n handlePointerMove = (event: PointerEvent) => {\n if (this.resizing) {\n const delta = getPage(this.resizing.axis, event) - this.resizing.page;\n if (this.resizing.axis === 'col') {\n const nextSize = Math.max(sizeColMin, Math.min(sizeColMax, this.resizing.size + delta));\n this.colSizes = { ...this.colSizes, [this.resizing.index]: nextSize };\n this.updateVisInline();\n } else {\n const nextSize = Math.max(sizeRowMin, Math.min(sizeRowMax, this.resizing.size + delta));\n this.rowSizes = { ...this.rowSizes, [this.resizing.index]: nextSize };\n this.updateVisBlock();\n }\n }\n };\n\n //\n // Accessors\n //\n\n private colSize(c: number | string) {\n return this.colSizes?.[c] ?? this.columnDefault.size;\n }\n\n private rowSize(r: number | string) {\n return this.rowSizes?.[r] ?? this.rowDefault.size;\n }\n\n private getCell(c: number | string, r: number | string) {\n return this.cells[`${c}${separator}${r}`];\n }\n\n //\n // Resize & reposition handlers, observer, ref\n //\n\n @state()\n observer = new ResizeObserver((entries) => {\n const { inlineSize, blockSize } = entries?.[0]?.contentBoxSize?.[0] ?? {\n inlineSize: 0,\n blockSize: 0,\n };\n if (\n Math.abs(inlineSize - this.sizeInline) > resizeTolerance ||\n Math.abs(blockSize - this.sizeBlock) > resizeTolerance\n ) {\n // console.info('[updating bounds]', 'resize', [inlineSize - this.sizeInline, blockSize - this.sizeBlock]);\n this.sizeInline = inlineSize;\n this.sizeBlock = blockSize;\n this.updateVis();\n }\n });\n\n viewportRef: Ref<HTMLDivElement> = createRef();\n\n handleWheel = ({ deltaX, deltaY }: WheelEvent) => {\n this.posInline = Math.max(0, this.posInline + deltaX);\n this.posBlock = Math.max(0, this.posBlock + deltaY);\n if (\n this.posInline >= this.binInlineMin &&\n this.posInline < this.binInlineMax &&\n this.posBlock >= this.binBlockMin &&\n this.posBlock < this.binBlockMax\n ) {\n // do nothing\n } else {\n // console.info(\n // '[updating bounds]',\n // 'wheel',\n // [this.binInlineMin, this.posInline, this.binInlineMax],\n // [this.binBlockMin, this.posBlock, this.binBlockMax],\n // );\n this.updateVis();\n }\n };\n\n private updateVisInline() {\n // todo: avoid starting from zero\n let colIndex = 0;\n let pxInline = this.colSize(colIndex);\n\n while (pxInline < this.posInline) {\n colIndex += 1;\n pxInline += this.colSize(colIndex) + gap;\n }\n\n this.visColMin = colIndex - overscanCol;\n\n this.binInlineMin = pxInline - this.colSize(colIndex) - gap;\n this.binInlineMax = pxInline + gap;\n\n this.overscanInline =\n [...Array(overscanCol)].reduce((acc, _, c0) => {\n acc += this.colSize(this.visColMin + c0);\n return acc;\n }, 0) +\n gap * (overscanCol - 1);\n\n while (pxInline < this.binInlineMax + this.sizeInline + gap) {\n colIndex += 1;\n pxInline += this.colSize(colIndex) + gap;\n }\n\n this.visColMax = colIndex + overscanCol;\n\n this.templateColumns = [...Array(this.visColMax - this.visColMin)]\n .map((_, c0) => `${this.colSize(this.visColMin + c0)}px`)\n .join(' ');\n }\n\n private updateVisBlock() {\n // todo: avoid starting from zero\n let rowIndex = 0;\n let pxBlock = this.rowSize(rowIndex);\n\n while (pxBlock < this.posBlock) {\n rowIndex += 1;\n pxBlock += this.rowSize(rowIndex) + gap;\n }\n\n this.visRowMin = rowIndex - overscanRow;\n\n this.binBlockMin = pxBlock - this.rowSize(rowIndex) - gap;\n this.binBlockMax = pxBlock + gap;\n\n this.overscanBlock =\n [...Array(overscanRow)].reduce((acc, _, r0) => {\n acc += this.rowSize(this.visRowMin + r0);\n return acc;\n }, 0) +\n gap * (overscanRow - 1);\n\n while (pxBlock < this.binBlockMax + this.sizeBlock) {\n rowIndex += 1;\n pxBlock += this.rowSize(rowIndex) + gap;\n }\n\n this.visRowMax = rowIndex + overscanRow;\n\n this.templateRows = [...Array(this.visRowMax - this.visRowMin)]\n .map((_, r0) => `${this.rowSize(this.visRowMin + r0)}px`)\n .join(' ');\n }\n\n private updateVis() {\n this.updateVisInline();\n this.updateVisBlock();\n }\n\n // Focus handlers\n\n @state()\n focusedCell: Record<DxGridAxis, number> = { col: 0, row: 0 };\n\n @state()\n focusActive: boolean = false;\n\n @eventOptions({ capture: true })\n handleFocus(event: FocusEvent) {\n const target = event.target as HTMLElement;\n const action = target.getAttribute('data-dx-grid-action');\n if (action === 'cell') {\n const c = parseInt(target.getAttribute('aria-colindex') ?? 'never');\n const r = parseInt(target.getAttribute('aria-rowindex') ?? 'never');\n this.focusedCell = { col: c, row: r };\n this.focusActive = true;\n }\n }\n\n @eventOptions({ capture: true })\n handleBlur(event: FocusEvent) {\n // Only unset `focusActive` if focus is not moving to an element within the grid.\n if (\n !event.relatedTarget ||\n (event.relatedTarget as HTMLElement).closest('.dx-grid__viewport') !== this.viewportRef.value\n ) {\n this.focusActive = false;\n }\n }\n\n /**\n * Moves focus to the cell with actual focus, otherwise moves focus to the viewport.\n */\n refocus() {\n (this.focusedCell.row < this.visRowMin ||\n this.focusedCell.row > this.visRowMax ||\n this.focusedCell.col < this.visColMin ||\n this.focusedCell.col > this.visColMax\n ? this.viewportRef.value\n : (this.viewportRef.value?.querySelector(\n `[aria-colindex=\"${this.focusedCell.col}\"][aria-rowindex=\"${this.focusedCell.row}\"]`,\n ) as HTMLElement | null)\n )?.focus({ preventScroll: true });\n }\n\n /**\n * Updates `pos` so that a cell in focus is fully within the viewport\n */\n snapPosToFocusedCell() {\n if (\n this.focusedCell.col < this.visColMin ||\n this.focusedCell.col > this.visColMax ||\n this.focusedCell.row < this.visRowMin ||\n this.focusedCell.row > this.visRowMax\n ) {\n // console.warn('Snapping position to a focused cell that is not already mounted is unsupported.');\n } else if (\n this.focusedCell.col > this.visColMin + overscanCol &&\n this.focusedCell.col < this.visColMax - overscanCol - 1 &&\n this.focusedCell.row > this.visRowMin + overscanRow &&\n this.focusedCell.row < this.visRowMax - overscanRow - 1\n ) {\n // console.log(\n // '[within bounds]',\n // this.focusedCell,\n // [this.visColMin, this.visColMax, overscanCol],\n // [this.visRowMin, this.visRowMax, overscanRow],\n // );\n } else {\n if (this.focusedCell.col <= this.visColMin + overscanCol) {\n this.posInline = this.binInlineMin;\n this.updateVisInline();\n } else if (this.focusedCell.col >= this.visColMax - overscanCol - 1) {\n const sizeSumCol = [...Array(this.focusedCell.col - this.visColMin)].reduce((acc, _, c0) => {\n acc += this.colSize(this.visColMin + overscanCol + c0) + gap;\n return acc;\n }, 0);\n this.posInline = this.binInlineMin + sizeSumCol + gap * 2 - this.sizeInline;\n this.updateVisInline();\n }\n\n if (this.focusedCell.row <= this.visRowMin + overscanRow) {\n this.posBlock = this.binBlockMin;\n this.updateVisBlock();\n } else if (this.focusedCell.row >= this.visRowMax - overscanRow - 1) {\n const sizeSumRow = [...Array(this.focusedCell.row - this.visRowMin)].reduce((acc, _, r0) => {\n acc += this.rowSize(this.visRowMin + overscanRow + r0) + gap;\n return acc;\n }, 0);\n this.posBlock = this.binBlockMin + sizeSumRow + gap * 2 - this.sizeBlock;\n this.updateVisBlock();\n }\n }\n }\n\n // Keyboard interactions\n handleKeydown(event: KeyboardEvent) {\n if (this.focusActive) {\n // Adjust state\n switch (event.key) {\n case 'ArrowDown':\n this.focusedCell = { ...this.focusedCell, row: this.focusedCell.row + 1 };\n break;\n case 'ArrowUp':\n this.focusedCell = { ...this.focusedCell, row: Math.max(0, this.focusedCell.row - 1) };\n break;\n case 'ArrowRight':\n this.focusedCell = { ...this.focusedCell, col: this.focusedCell.col + 1 };\n break;\n case 'ArrowLeft':\n this.focusedCell = { ...this.focusedCell, col: Math.max(0, this.focusedCell.col - 1) };\n break;\n }\n // Handle virtualization & focus consequences\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n case 'ArrowRight':\n case 'ArrowLeft':\n event.preventDefault();\n this.snapPosToFocusedCell();\n break;\n }\n }\n }\n\n //\n // Render and other lifecycle methods\n //\n\n override render() {\n const visibleCols = this.visColMax - this.visColMin;\n const visibleRows = this.visRowMax - this.visRowMin;\n const offsetInline = gap + this.binInlineMin - this.posInline - this.overscanInline;\n const offsetBlock = gap + this.binBlockMin - this.posBlock - this.overscanBlock;\n\n return html`<div\n role=\"none\"\n class=\"dx-grid\"\n @pointerdown=${this.handlePointerDown}\n @pointerup=${this.handlePointerUp}\n @pointermove=${this.handlePointerMove}\n @focus=${this.handleFocus}\n @blur=${this.handleBlur}\n @keydown=${this.handleKeydown}\n >\n <div role=\"none\" class=\"dx-grid__corner\"></div>\n <div role=\"none\" class=\"dx-grid__columnheader\">\n <div\n role=\"none\"\n class=\"dx-grid__columnheader__content\"\n style=\"transform:translate3d(${offsetInline}px,0,0);grid-template-columns:${this.templateColumns};\"\n >\n ${[...Array(visibleCols)].map((_, c0) => {\n const c = this.visColMin + c0;\n return html`<div\n role=\"columnheader\"\n ?inert=${c < 0}\n style=\"block-size:${this.rowDefault.size}px;grid-column:${c0 + 1}/${c0 + 2};\"\n >\n <span id=${localChId(c0)}>${colToA1Notation(c)}</span>\n ${(this.columns[c]?.resizeable ?? this.columnDefault.resizeable) &&\n html`<button class=\"dx-grid__resize-handle\" data-dx-grid-action=${`resize-col,${c}`}>\n <span class=\"sr-only\">Resize</span>\n </button>`}\n </div>`;\n })}\n </div>\n </div>\n <div role=\"none\" class=\"dx-grid__corner\"></div>\n <div role=\"none\" class=\"dx-grid__rowheader\">\n <div\n role=\"none\"\n class=\"dx-grid__rowheader__content\"\n style=\"transform:translate3d(0,${offsetBlock}px,0);grid-template-rows:${this.templateRows};\"\n >\n ${[...Array(visibleRows)].map((_, r0) => {\n const r = this.visRowMin + r0;\n return html`<div role=\"rowheader\" ?inert=${r < 0} style=\"grid-row:${r0 + 1}/${r0 + 2}\">\n <span id=${localRhId(r0)}>${rowToA1Notation(r)}</span>\n ${(this.rows[r]?.resizeable ?? this.rowDefault.resizeable) &&\n html`<button class=\"dx-grid__resize-handle\" data-dx-grid-action=${`resize-row,${r}`}>\n <span class=\"sr-only\">Resize</span>\n </button>`}\n </div>`;\n })}\n </div>\n </div>\n <div role=\"grid\" class=\"dx-grid__viewport\" tabindex=\"0\" @wheel=${this.handleWheel} ${ref(this.viewportRef)}>\n <div\n role=\"none\"\n class=\"dx-grid__content\"\n style=\"transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this\n .templateColumns};grid-template-rows:${this.templateRows};\"\n >\n ${[...Array(visibleCols)].map((_, c0) => {\n return [...Array(visibleRows)].map((_, r0) => {\n const c = c0 + this.visColMin;\n const r = r0 + this.visRowMin;\n const cell = this.getCell(c, r);\n return html`<div\n role=\"gridcell\"\n tabindex=\"0\"\n ?inert=${c < 0 || r < 0}\n aria-rowindex=${r}\n aria-colindex=${c}\n data-dx-grid-action=\"cell\"\n style=\"grid-column:${c0 + 1};grid-row:${r0 + 1}\"\n >\n ${cell?.value}\n </div>`;\n });\n })}\n </div>\n </div>\n <div role=\"none\" class=\"dx-grid__scrollbar\" aria-orientation=\"vertical\">\n <div role=\"none\" class=\"dx-grid__scrollbar__thumb\"></div>\n </div>\n <div role=\"none\" class=\"dx-grid__corner\"></div>\n <div role=\"none\" class=\"dx-grid__scrollbar\" aria-orientation=\"horizontal\">\n <div role=\"none\" class=\"dx-grid__scrollbar__thumb\"></div>\n </div>\n <div role=\"none\" class=\"dx-grid__corner\"></div>\n </div>`;\n }\n\n override firstUpdated() {\n this.observer.observe(this.viewportRef.value!);\n this.colSizes = Object.entries(this.columns).reduce((acc: Record<string, number>, [colId, colMeta]) => {\n if (colMeta?.size) {\n acc[colId] = colMeta.size;\n }\n return acc;\n }, {});\n this.rowSizes = Object.entries(this.rows).reduce((acc: Record<string, number>, [rowId, rowMeta]) => {\n if (rowMeta?.size) {\n acc[rowId] = rowMeta.size;\n }\n return acc;\n }, {});\n }\n\n override updated(changedProperties: Map<string, any>) {\n // Update the focused element if there is a change in bounds (otherwise Lit keeps focus on the relative element).\n if (\n this.focusActive &&\n (changedProperties.has('visRowMin') || changedProperties.has('visColMin') || changedProperties.has('focusedCell'))\n ) {\n this.refocus();\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n // console.log('[disconnected]', this.viewportRef.value);\n // TODO(thure): Will this even work?\n if (this.viewportRef.value) {\n this.observer.unobserve(this.viewportRef.value);\n }\n }\n\n override createRenderRoot() {\n return this;\n }\n}\n", "//\n// Copyright 2024 DXOS.org\n//\n\nexport type DxGridAxis = 'row' | 'col';\n\nexport type DxAxisResizeProps = Pick<DxAxisResize, 'axis' | 'index' | 'size'>;\n\nexport class DxAxisResize extends Event {\n public readonly axis: DxGridAxis;\n public readonly index: string;\n public readonly size: number;\n constructor(props: DxAxisResizeProps) {\n super('dx-axis-resize');\n this.axis = props.axis;\n this.index = props.index;\n this.size = props.size;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["LitElement", "html", "customElement", "state", "property", "eventOptions", "ref", "createRef", "DxAxisResize", "Event", "constructor", "props", "axis", "index", "size", "gap", "resizeTolerance", "overscanCol", "overscanRow", "sizeColMin", "sizeColMax", "sizeRowMin", "sizeRowMax", "separator", "colToA1Notation", "col", "String", "fromCharCode", "charCodeAt", "Math", "floor", "rowToA1Notation", "row", "localChId", "c0", "localRhId", "r0", "getPage", "axis", "event", "pageX", "pageY", "DxGrid", "LitElement", "rowDefault", "size", "columnDefault", "rows", "columns", "cells", "posInline", "posBlock", "sizeInline", "sizeBlock", "overscanInline", "overscanBlock", "binInlineMin", "binInlineMax", "colSize", "binBlockMin", "binBlockMax", "rowSize", "visColMin", "visColMax", "visRowMin", "visRowMax", "templateColumns", "templateRows", "colSizes", "rowSizes", "resizing", "handlePointerDown", "actionEl", "target", "closest", "action", "getAttribute", "startsWith", "resize", "index", "split", "_", "page", "handlePointerUp", "_event", "resizeEvent", "DxAxisResize", "dispatchEvent", "handlePointerMove", "delta", "nextSize", "max", "min", "updateVisInline", "updateVisBlock", "observer", "ResizeObserver", "entries", "inlineSize", "blockSize", "contentBoxSize", "abs", "updateVis", "viewportRef", "createRef", "handleWheel", "deltaX", "deltaY", "focusedCell", "focusActive", "c", "r", "getCell", "colIndex", "pxInline", "Array", "reduce", "acc", "map", "join", "rowIndex", "pxBlock", "handleFocus", "parseInt", "handleBlur", "relatedTarget", "value", "refocus", "querySelector", "focus", "preventScroll", "snapPosToFocusedCell", "sizeSumCol", "sizeSumRow", "handleKeydown", "key", "preventDefault", "render", "visibleCols", "visibleRows", "offsetInline", "offsetBlock", "html", "resizeable", "ref", "cell", "firstUpdated", "observe", "Object", "colId", "colMeta", "rowId", "rowMeta", "updated", "changedProperties", "has", "disconnectedCallback", "unobserve", "createRenderRoot", "property", "type", "state", "eventOptions", "capture", "customElement"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/lit-grid/src/dx-grid.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/lit-grid/src/types.ts":{"bytes":1636,"imports":[],"format":"esm"},"packages/ui/lit-grid/src/dx-grid.ts":{"bytes":69997,"imports":[{"path":"lit","kind":"import-statement","external":true},{"path":"lit/decorators.js","kind":"import-statement","external":true},{"path":"lit/directives/ref.js","kind":"import-statement","external":true},{"path":"packages/ui/lit-grid/src/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"},"packages/ui/lit-grid/src/index.ts":{"bytes":572,"imports":[{"path":"packages/ui/lit-grid/src/dx-grid.ts","kind":"import-statement","original":"./dx-grid"},{"path":"packages/ui/lit-grid/src/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"}},"outputs":{"packages/ui/lit-grid/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":33648},"packages/ui/lit-grid/dist/lib/browser/index.mjs":{"imports":[{"path":"lit","kind":"import-statement","external":true},{"path":"lit/decorators.js","kind":"import-statement","external":true},{"path":"lit/directives/ref.js","kind":"import-statement","external":true}],"exports":["DxAxisResize","DxGrid"],"entryPoint":"packages/ui/lit-grid/src/index.ts","inputs":{"packages/ui/lit-grid/src/dx-grid.ts":{"bytesInOutput":18568},"packages/ui/lit-grid/src/types.ts":{"bytesInOutput":186},"packages/ui/lit-grid/src/index.ts":{"bytesInOutput":0}},"bytes":18943}}}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LitElement } from 'lit';
|
|
2
2
|
import { type Ref } from 'lit/directives/ref.js';
|
|
3
|
+
import { type DxAxisResizeProps, type DxGridAxis } from './types';
|
|
3
4
|
export type CellValue = {
|
|
4
5
|
/**
|
|
5
6
|
* The content value
|
|
@@ -19,7 +20,7 @@ type AxisMeta = {
|
|
|
19
20
|
description?: string;
|
|
20
21
|
resizeable?: boolean;
|
|
21
22
|
};
|
|
22
|
-
export type DxGridProps = Pick<DxGrid, 'cells' | 'rows' | 'columns' | 'rowDefault' | 'columnDefault'
|
|
23
|
+
export type DxGridProps = Partial<Pick<DxGrid, 'cells' | 'rows' | 'columns' | 'rowDefault' | 'columnDefault'>>;
|
|
23
24
|
export declare class DxGrid extends LitElement {
|
|
24
25
|
rowDefault: AxisMeta;
|
|
25
26
|
columnDefault: AxisMeta;
|
|
@@ -44,12 +45,9 @@ export declare class DxGrid extends LitElement {
|
|
|
44
45
|
templateRows: string;
|
|
45
46
|
colSizes: Record<string, number>;
|
|
46
47
|
rowSizes: Record<string, number>;
|
|
47
|
-
resizing: null | {
|
|
48
|
-
axis: 'col' | 'row';
|
|
48
|
+
resizing: null | (DxAxisResizeProps & {
|
|
49
49
|
page: number;
|
|
50
|
-
|
|
51
|
-
index: string;
|
|
52
|
-
};
|
|
50
|
+
});
|
|
53
51
|
handlePointerDown: (event: PointerEvent) => void;
|
|
54
52
|
handlePointerUp: (_event: PointerEvent) => void;
|
|
55
53
|
handlePointerMove: (event: PointerEvent) => void;
|
|
@@ -62,8 +60,22 @@ export declare class DxGrid extends LitElement {
|
|
|
62
60
|
private updateVisInline;
|
|
63
61
|
private updateVisBlock;
|
|
64
62
|
private updateVis;
|
|
63
|
+
focusedCell: Record<DxGridAxis, number>;
|
|
64
|
+
focusActive: boolean;
|
|
65
|
+
handleFocus(event: FocusEvent): void;
|
|
66
|
+
handleBlur(event: FocusEvent): void;
|
|
67
|
+
/**
|
|
68
|
+
* Moves focus to the cell with actual focus, otherwise moves focus to the viewport.
|
|
69
|
+
*/
|
|
70
|
+
refocus(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Updates `pos` so that a cell in focus is fully within the viewport
|
|
73
|
+
*/
|
|
74
|
+
snapPosToFocusedCell(): void;
|
|
75
|
+
handleKeydown(event: KeyboardEvent): void;
|
|
65
76
|
render(): import("lit").TemplateResult<1>;
|
|
66
77
|
firstUpdated(): void;
|
|
78
|
+
updated(changedProperties: Map<string, any>): void;
|
|
67
79
|
disconnectedCallback(): void;
|
|
68
80
|
createRenderRoot(): this;
|
|
69
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dx-grid.d.ts","sourceRoot":"","sources":["../../../src/dx-grid.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAQ,MAAM,KAAK,CAAC;AAEvC,OAAO,EAAkB,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AA+
|
|
1
|
+
{"version":3,"file":"dx-grid.d.ts","sourceRoot":"","sources":["../../../src/dx-grid.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAQ,MAAM,KAAK,CAAC;AAEvC,OAAO,EAAkB,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAEjE,OAAO,EAAgB,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AA+ChF,MAAM,MAAM,SAAS,GAAG;IACtB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,KAAK,QAAQ,GAAG;IACd,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,eAAe,CAAC,CAAC,CAAC;AAO/G,qBACa,MAAO,SAAQ,UAAU;IAEpC,UAAU,EAAE,QAAQ,CAAgB;IAGpC,aAAa,EAAE,QAAQ,CAAiB;IAGxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAM;IAGpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAM;IAGvC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAM;IAOtC,SAAS,SAAK;IAGd,QAAQ,SAAK;IAOb,UAAU,SAAK;IAGf,SAAS,SAAK;IAOd,cAAc,SAAK;IAGnB,aAAa,SAAK;IAOlB,YAAY,SAAK;IAGjB,YAAY,SAAmB;IAG/B,WAAW,SAAK;IAGhB,WAAW,SAAmB;IAQ9B,SAAS,SAAK;IAGd,SAAS,SAAK;IAGd,SAAS,SAAK;IAGd,SAAS,SAAK;IAMd,eAAe,SAA0B;IAGzC,YAAY,SAA0B;IAOtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAGtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAGtC,QAAQ,EAAE,IAAI,GAAG,CAAC,iBAAiB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAQ;IAE/D,iBAAiB,UAAW,YAAY,UAetC;IAEF,eAAe,WAAY,YAAY,UAUrC;IAEF,iBAAiB,UAAW,YAAY,UAatC;IAMF,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,OAAO;IASf,QAAQ,iBAcL;IAEH,WAAW,EAAE,GAAG,CAAC,cAAc,CAAC,CAAe;IAE/C,WAAW,uBAAwB,UAAU,UAmB3C;IAEF,OAAO,CAAC,eAAe;IAkCvB,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,SAAS;IAQjB,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAsB;IAG7D,WAAW,EAAE,OAAO,CAAS;IAG7B,WAAW,CAAC,KAAK,EAAE,UAAU;IAY7B,UAAU,CAAC,KAAK,EAAE,UAAU;IAU5B;;OAEG;IACH,OAAO;IAYP;;OAEG;IACH,oBAAoB;IAgDpB,aAAa,CAAC,KAAK,EAAE,aAAa;IAkCzB,MAAM;IAgGN,YAAY;IAgBZ,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC;IAU3C,oBAAoB;IASpB,gBAAgB;CAG1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAIA,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type DxGridAxis = 'row' | 'col';
|
|
2
|
+
export type DxAxisResizeProps = Pick<DxAxisResize, 'axis' | 'index' | 'size'>;
|
|
3
|
+
export declare class DxAxisResize extends Event {
|
|
4
|
+
readonly axis: DxGridAxis;
|
|
5
|
+
readonly index: string;
|
|
6
|
+
readonly size: number;
|
|
7
|
+
constructor(props: DxAxisResizeProps);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,KAAK,CAAC;AAEvC,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAE9E,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAgB,IAAI,EAAE,UAAU,CAAC;IACjC,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,IAAI,EAAE,MAAM,CAAC;gBACjB,KAAK,EAAE,iBAAiB;CAMrC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/lit-grid",
|
|
3
|
-
"version": "0.6.
|
|
4
|
-
"description": "A grid
|
|
3
|
+
"version": "0.6.11-staging.32b42e4",
|
|
4
|
+
"description": "A grid Web Component using Lit",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
7
7
|
"license": "MIT",
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
},
|
|
14
14
|
"./dx-grid.pcss": "./src/dx-grid.pcss"
|
|
15
15
|
},
|
|
16
|
-
"
|
|
16
|
+
"types": "dist/types/src/index.d.ts",
|
|
17
|
+
"typesVersions": {
|
|
18
|
+
"*": {}
|
|
19
|
+
},
|
|
17
20
|
"files": [
|
|
18
21
|
"src",
|
|
19
22
|
"dist"
|
package/src/dx-grid.pcss
CHANGED
|
@@ -21,6 +21,7 @@ dx-grid {
|
|
|
21
21
|
grid-template-columns: min-content 1fr min-content;
|
|
22
22
|
grid-template-rows: min-content 1fr min-content;
|
|
23
23
|
font-variant-numeric: tabular-nums;
|
|
24
|
+
--dx-grid-gap: 1px;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
.dx-grid__scrollbar__thumb {
|
|
@@ -38,8 +39,8 @@ dx-grid {
|
|
|
38
39
|
.dx-grid__rowheader__content,
|
|
39
40
|
.dx-grid__content {
|
|
40
41
|
display: grid;
|
|
41
|
-
gap:
|
|
42
|
-
background: var(--dx-separator);
|
|
42
|
+
gap: var(--dx-grid-gap);
|
|
43
|
+
background: var(--dx-grid-lines, var(--dx-separator));
|
|
43
44
|
inline-size: min-content;
|
|
44
45
|
block-size: min-content;
|
|
45
46
|
}
|
|
@@ -48,27 +49,46 @@ dx-grid {
|
|
|
48
49
|
.dx-grid__rowheader,
|
|
49
50
|
.dx-grid__viewport {
|
|
50
51
|
overflow: hidden;
|
|
52
|
+
position: relative;
|
|
53
|
+
&:focus-visible {
|
|
54
|
+
outline: none;
|
|
55
|
+
}
|
|
56
|
+
&:focus-visible::after {
|
|
57
|
+
content: "";
|
|
58
|
+
position: absolute;
|
|
59
|
+
inset: 0;
|
|
60
|
+
pointer-events: none;
|
|
61
|
+
border: 1px solid var(--dx-accentSurface);
|
|
62
|
+
}
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
.dx-grid__columnheader__content {
|
|
54
|
-
border-block-end: 2px solid var(--dx-separator);
|
|
55
|
-
grid-template-columns: repeat(99, 64px);
|
|
66
|
+
border-block-end: 2px solid var(--dx-grid-lines, var(--dx-separator));
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
.dx-grid__rowheader__content {
|
|
59
|
-
border-inline-end: 2px solid var(--dx-separator);
|
|
70
|
+
border-inline-end: 2px solid var(--dx-grid-lines, var(--dx-separator));
|
|
60
71
|
grid-template-columns: min-content;
|
|
61
72
|
text-align: end;
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
.dx-grid {
|
|
65
76
|
[role='gridcell'], [role='columnheader'], [role='rowheader'] {
|
|
66
|
-
background: var(--dx-base);
|
|
77
|
+
background: var(--dx-grid-base, var(--dx-base));
|
|
67
78
|
padding: 2px;
|
|
68
79
|
box-sizing: border-box;
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
border: 1px solid transparent;
|
|
69
82
|
&[inert] {
|
|
70
83
|
visibility: hidden;
|
|
71
84
|
}
|
|
85
|
+
&:focus, &:focus-visible {
|
|
86
|
+
cursor: text;
|
|
87
|
+
position: relative;
|
|
88
|
+
z-index: 2;
|
|
89
|
+
border-color: var(--dx-accentSurface);
|
|
90
|
+
outline: none;
|
|
91
|
+
}
|
|
72
92
|
}
|
|
73
93
|
}
|
|
74
94
|
|
|
@@ -80,7 +100,7 @@ dx-grid {
|
|
|
80
100
|
position: absolute;
|
|
81
101
|
background: transparent;
|
|
82
102
|
&:hover {
|
|
83
|
-
background: var(--dx-hoverSurface)
|
|
103
|
+
background: var(--dx-grid-resizeHandleHover, var(--dx-hoverSurface));
|
|
84
104
|
}
|
|
85
105
|
}
|
|
86
106
|
}
|
package/src/dx-grid.ts
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { LitElement, html } from 'lit';
|
|
6
|
-
import { customElement, state, property } from 'lit/decorators.js';
|
|
6
|
+
import { customElement, state, property, eventOptions } from 'lit/decorators.js';
|
|
7
7
|
import { ref, createRef, type Ref } from 'lit/directives/ref.js';
|
|
8
8
|
|
|
9
|
+
import { DxAxisResize, type DxAxisResizeProps, type DxGridAxis } from './types';
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* The size in pixels of the gap between cells
|
|
11
13
|
*/
|
|
@@ -72,7 +74,7 @@ type AxisMeta = {
|
|
|
72
74
|
resizeable?: boolean;
|
|
73
75
|
};
|
|
74
76
|
|
|
75
|
-
export type DxGridProps = Pick<DxGrid, 'cells' | 'rows' | 'columns' | 'rowDefault' | 'columnDefault'
|
|
77
|
+
export type DxGridProps = Partial<Pick<DxGrid, 'cells' | 'rows' | 'columns' | 'rowDefault' | 'columnDefault'>>;
|
|
76
78
|
|
|
77
79
|
const localChId = (c0: number) => `ch--${c0}`;
|
|
78
80
|
const localRhId = (r0: number) => `rh--${r0}`;
|
|
@@ -179,7 +181,7 @@ export class DxGrid extends LitElement {
|
|
|
179
181
|
rowSizes: Record<string, number> = {};
|
|
180
182
|
|
|
181
183
|
@state()
|
|
182
|
-
resizing: null |
|
|
184
|
+
resizing: null | (DxAxisResizeProps & { page: number }) = null;
|
|
183
185
|
|
|
184
186
|
handlePointerDown = (event: PointerEvent) => {
|
|
185
187
|
const actionEl = (event.target as HTMLElement)?.closest('[data-dx-grid-action]');
|
|
@@ -189,7 +191,7 @@ export class DxGrid extends LitElement {
|
|
|
189
191
|
const [resize, index] = action.split(',');
|
|
190
192
|
const [_, axis] = resize.split('-');
|
|
191
193
|
this.resizing = {
|
|
192
|
-
axis: axis as
|
|
194
|
+
axis: axis as DxGridAxis,
|
|
193
195
|
size: axis === 'col' ? this.colSize(index) : this.rowSize(index),
|
|
194
196
|
page: getPage(axis, event),
|
|
195
197
|
index,
|
|
@@ -199,7 +201,15 @@ export class DxGrid extends LitElement {
|
|
|
199
201
|
};
|
|
200
202
|
|
|
201
203
|
handlePointerUp = (_event: PointerEvent) => {
|
|
202
|
-
this.resizing
|
|
204
|
+
if (this.resizing) {
|
|
205
|
+
const resizeEvent = new DxAxisResize({
|
|
206
|
+
axis: this.resizing.axis,
|
|
207
|
+
index: this.resizing.index,
|
|
208
|
+
size: this[this.resizing.axis === 'col' ? 'colSize' : 'rowSize'](this.resizing.index),
|
|
209
|
+
});
|
|
210
|
+
this.dispatchEvent(resizeEvent);
|
|
211
|
+
this.resizing = null;
|
|
212
|
+
}
|
|
203
213
|
};
|
|
204
214
|
|
|
205
215
|
handlePointerMove = (event: PointerEvent) => {
|
|
@@ -299,12 +309,12 @@ export class DxGrid extends LitElement {
|
|
|
299
309
|
}, 0) +
|
|
300
310
|
gap * (overscanCol - 1);
|
|
301
311
|
|
|
302
|
-
while (pxInline < this.binInlineMax + this.sizeInline) {
|
|
312
|
+
while (pxInline < this.binInlineMax + this.sizeInline + gap) {
|
|
303
313
|
colIndex += 1;
|
|
304
314
|
pxInline += this.colSize(colIndex) + gap;
|
|
305
315
|
}
|
|
306
316
|
|
|
307
|
-
this.visColMax = colIndex + overscanCol
|
|
317
|
+
this.visColMax = colIndex + overscanCol;
|
|
308
318
|
|
|
309
319
|
this.templateColumns = [...Array(this.visColMax - this.visColMin)]
|
|
310
320
|
.map((_, c0) => `${this.colSize(this.visColMin + c0)}px`)
|
|
@@ -338,7 +348,7 @@ export class DxGrid extends LitElement {
|
|
|
338
348
|
pxBlock += this.rowSize(rowIndex) + gap;
|
|
339
349
|
}
|
|
340
350
|
|
|
341
|
-
this.visRowMax = rowIndex + overscanRow
|
|
351
|
+
this.visRowMax = rowIndex + overscanRow;
|
|
342
352
|
|
|
343
353
|
this.templateRows = [...Array(this.visRowMax - this.visRowMin)]
|
|
344
354
|
.map((_, r0) => `${this.rowSize(this.visRowMin + r0)}px`)
|
|
@@ -350,6 +360,133 @@ export class DxGrid extends LitElement {
|
|
|
350
360
|
this.updateVisBlock();
|
|
351
361
|
}
|
|
352
362
|
|
|
363
|
+
// Focus handlers
|
|
364
|
+
|
|
365
|
+
@state()
|
|
366
|
+
focusedCell: Record<DxGridAxis, number> = { col: 0, row: 0 };
|
|
367
|
+
|
|
368
|
+
@state()
|
|
369
|
+
focusActive: boolean = false;
|
|
370
|
+
|
|
371
|
+
@eventOptions({ capture: true })
|
|
372
|
+
handleFocus(event: FocusEvent) {
|
|
373
|
+
const target = event.target as HTMLElement;
|
|
374
|
+
const action = target.getAttribute('data-dx-grid-action');
|
|
375
|
+
if (action === 'cell') {
|
|
376
|
+
const c = parseInt(target.getAttribute('aria-colindex') ?? 'never');
|
|
377
|
+
const r = parseInt(target.getAttribute('aria-rowindex') ?? 'never');
|
|
378
|
+
this.focusedCell = { col: c, row: r };
|
|
379
|
+
this.focusActive = true;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
@eventOptions({ capture: true })
|
|
384
|
+
handleBlur(event: FocusEvent) {
|
|
385
|
+
// Only unset `focusActive` if focus is not moving to an element within the grid.
|
|
386
|
+
if (
|
|
387
|
+
!event.relatedTarget ||
|
|
388
|
+
(event.relatedTarget as HTMLElement).closest('.dx-grid__viewport') !== this.viewportRef.value
|
|
389
|
+
) {
|
|
390
|
+
this.focusActive = false;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Moves focus to the cell with actual focus, otherwise moves focus to the viewport.
|
|
396
|
+
*/
|
|
397
|
+
refocus() {
|
|
398
|
+
(this.focusedCell.row < this.visRowMin ||
|
|
399
|
+
this.focusedCell.row > this.visRowMax ||
|
|
400
|
+
this.focusedCell.col < this.visColMin ||
|
|
401
|
+
this.focusedCell.col > this.visColMax
|
|
402
|
+
? this.viewportRef.value
|
|
403
|
+
: (this.viewportRef.value?.querySelector(
|
|
404
|
+
`[aria-colindex="${this.focusedCell.col}"][aria-rowindex="${this.focusedCell.row}"]`,
|
|
405
|
+
) as HTMLElement | null)
|
|
406
|
+
)?.focus({ preventScroll: true });
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Updates `pos` so that a cell in focus is fully within the viewport
|
|
411
|
+
*/
|
|
412
|
+
snapPosToFocusedCell() {
|
|
413
|
+
if (
|
|
414
|
+
this.focusedCell.col < this.visColMin ||
|
|
415
|
+
this.focusedCell.col > this.visColMax ||
|
|
416
|
+
this.focusedCell.row < this.visRowMin ||
|
|
417
|
+
this.focusedCell.row > this.visRowMax
|
|
418
|
+
) {
|
|
419
|
+
// console.warn('Snapping position to a focused cell that is not already mounted is unsupported.');
|
|
420
|
+
} else if (
|
|
421
|
+
this.focusedCell.col > this.visColMin + overscanCol &&
|
|
422
|
+
this.focusedCell.col < this.visColMax - overscanCol - 1 &&
|
|
423
|
+
this.focusedCell.row > this.visRowMin + overscanRow &&
|
|
424
|
+
this.focusedCell.row < this.visRowMax - overscanRow - 1
|
|
425
|
+
) {
|
|
426
|
+
// console.log(
|
|
427
|
+
// '[within bounds]',
|
|
428
|
+
// this.focusedCell,
|
|
429
|
+
// [this.visColMin, this.visColMax, overscanCol],
|
|
430
|
+
// [this.visRowMin, this.visRowMax, overscanRow],
|
|
431
|
+
// );
|
|
432
|
+
} else {
|
|
433
|
+
if (this.focusedCell.col <= this.visColMin + overscanCol) {
|
|
434
|
+
this.posInline = this.binInlineMin;
|
|
435
|
+
this.updateVisInline();
|
|
436
|
+
} else if (this.focusedCell.col >= this.visColMax - overscanCol - 1) {
|
|
437
|
+
const sizeSumCol = [...Array(this.focusedCell.col - this.visColMin)].reduce((acc, _, c0) => {
|
|
438
|
+
acc += this.colSize(this.visColMin + overscanCol + c0) + gap;
|
|
439
|
+
return acc;
|
|
440
|
+
}, 0);
|
|
441
|
+
this.posInline = this.binInlineMin + sizeSumCol + gap * 2 - this.sizeInline;
|
|
442
|
+
this.updateVisInline();
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (this.focusedCell.row <= this.visRowMin + overscanRow) {
|
|
446
|
+
this.posBlock = this.binBlockMin;
|
|
447
|
+
this.updateVisBlock();
|
|
448
|
+
} else if (this.focusedCell.row >= this.visRowMax - overscanRow - 1) {
|
|
449
|
+
const sizeSumRow = [...Array(this.focusedCell.row - this.visRowMin)].reduce((acc, _, r0) => {
|
|
450
|
+
acc += this.rowSize(this.visRowMin + overscanRow + r0) + gap;
|
|
451
|
+
return acc;
|
|
452
|
+
}, 0);
|
|
453
|
+
this.posBlock = this.binBlockMin + sizeSumRow + gap * 2 - this.sizeBlock;
|
|
454
|
+
this.updateVisBlock();
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Keyboard interactions
|
|
460
|
+
handleKeydown(event: KeyboardEvent) {
|
|
461
|
+
if (this.focusActive) {
|
|
462
|
+
// Adjust state
|
|
463
|
+
switch (event.key) {
|
|
464
|
+
case 'ArrowDown':
|
|
465
|
+
this.focusedCell = { ...this.focusedCell, row: this.focusedCell.row + 1 };
|
|
466
|
+
break;
|
|
467
|
+
case 'ArrowUp':
|
|
468
|
+
this.focusedCell = { ...this.focusedCell, row: Math.max(0, this.focusedCell.row - 1) };
|
|
469
|
+
break;
|
|
470
|
+
case 'ArrowRight':
|
|
471
|
+
this.focusedCell = { ...this.focusedCell, col: this.focusedCell.col + 1 };
|
|
472
|
+
break;
|
|
473
|
+
case 'ArrowLeft':
|
|
474
|
+
this.focusedCell = { ...this.focusedCell, col: Math.max(0, this.focusedCell.col - 1) };
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
// Handle virtualization & focus consequences
|
|
478
|
+
switch (event.key) {
|
|
479
|
+
case 'ArrowDown':
|
|
480
|
+
case 'ArrowUp':
|
|
481
|
+
case 'ArrowRight':
|
|
482
|
+
case 'ArrowLeft':
|
|
483
|
+
event.preventDefault();
|
|
484
|
+
this.snapPosToFocusedCell();
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
353
490
|
//
|
|
354
491
|
// Render and other lifecycle methods
|
|
355
492
|
//
|
|
@@ -357,9 +494,8 @@ export class DxGrid extends LitElement {
|
|
|
357
494
|
override render() {
|
|
358
495
|
const visibleCols = this.visColMax - this.visColMin;
|
|
359
496
|
const visibleRows = this.visRowMax - this.visRowMin;
|
|
360
|
-
|
|
361
|
-
const
|
|
362
|
-
const offsetBlock = this.binBlockMin - this.posBlock - this.overscanBlock;
|
|
497
|
+
const offsetInline = gap + this.binInlineMin - this.posInline - this.overscanInline;
|
|
498
|
+
const offsetBlock = gap + this.binBlockMin - this.posBlock - this.overscanBlock;
|
|
363
499
|
|
|
364
500
|
return html`<div
|
|
365
501
|
role="none"
|
|
@@ -367,6 +503,9 @@ export class DxGrid extends LitElement {
|
|
|
367
503
|
@pointerdown=${this.handlePointerDown}
|
|
368
504
|
@pointerup=${this.handlePointerUp}
|
|
369
505
|
@pointermove=${this.handlePointerMove}
|
|
506
|
+
@focus=${this.handleFocus}
|
|
507
|
+
@blur=${this.handleBlur}
|
|
508
|
+
@keydown=${this.handleKeydown}
|
|
370
509
|
>
|
|
371
510
|
<div role="none" class="dx-grid__corner"></div>
|
|
372
511
|
<div role="none" class="dx-grid__columnheader">
|
|
@@ -380,8 +519,7 @@ export class DxGrid extends LitElement {
|
|
|
380
519
|
return html`<div
|
|
381
520
|
role="columnheader"
|
|
382
521
|
?inert=${c < 0}
|
|
383
|
-
style="
|
|
384
|
-
2};"
|
|
522
|
+
style="block-size:${this.rowDefault.size}px;grid-column:${c0 + 1}/${c0 + 2};"
|
|
385
523
|
>
|
|
386
524
|
<span id=${localChId(c0)}>${colToA1Notation(c)}</span>
|
|
387
525
|
${(this.columns[c]?.resizeable ?? this.columnDefault.resizeable) &&
|
|
@@ -394,14 +532,14 @@ export class DxGrid extends LitElement {
|
|
|
394
532
|
</div>
|
|
395
533
|
<div role="none" class="dx-grid__corner"></div>
|
|
396
534
|
<div role="none" class="dx-grid__rowheader">
|
|
397
|
-
<div
|
|
535
|
+
<div
|
|
536
|
+
role="none"
|
|
537
|
+
class="dx-grid__rowheader__content"
|
|
538
|
+
style="transform:translate3d(0,${offsetBlock}px,0);grid-template-rows:${this.templateRows};"
|
|
539
|
+
>
|
|
398
540
|
${[...Array(visibleRows)].map((_, r0) => {
|
|
399
541
|
const r = this.visRowMin + r0;
|
|
400
|
-
return html`<div
|
|
401
|
-
role="rowheader"
|
|
402
|
-
?inert=${r < 0}
|
|
403
|
-
style="block-size:${this.rowSize(r)}px;grid-row:${r0 + 1}/${r0 + 2}"
|
|
404
|
-
>
|
|
542
|
+
return html`<div role="rowheader" ?inert=${r < 0} style="grid-row:${r0 + 1}/${r0 + 2}">
|
|
405
543
|
<span id=${localRhId(r0)}>${rowToA1Notation(r)}</span>
|
|
406
544
|
${(this.rows[r]?.resizeable ?? this.rowDefault.resizeable) &&
|
|
407
545
|
html`<button class="dx-grid__resize-handle" data-dx-grid-action=${`resize-row,${r}`}>
|
|
@@ -411,9 +549,9 @@ export class DxGrid extends LitElement {
|
|
|
411
549
|
})}
|
|
412
550
|
</div>
|
|
413
551
|
</div>
|
|
414
|
-
<div role="
|
|
552
|
+
<div role="grid" class="dx-grid__viewport" tabindex="0" @wheel=${this.handleWheel} ${ref(this.viewportRef)}>
|
|
415
553
|
<div
|
|
416
|
-
role="
|
|
554
|
+
role="none"
|
|
417
555
|
class="dx-grid__content"
|
|
418
556
|
style="transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this
|
|
419
557
|
.templateColumns};grid-template-rows:${this.templateRows};"
|
|
@@ -425,6 +563,7 @@ export class DxGrid extends LitElement {
|
|
|
425
563
|
const cell = this.getCell(c, r);
|
|
426
564
|
return html`<div
|
|
427
565
|
role="gridcell"
|
|
566
|
+
tabindex="0"
|
|
428
567
|
?inert=${c < 0 || r < 0}
|
|
429
568
|
aria-rowindex=${r}
|
|
430
569
|
aria-colindex=${c}
|
|
@@ -464,6 +603,16 @@ export class DxGrid extends LitElement {
|
|
|
464
603
|
}, {});
|
|
465
604
|
}
|
|
466
605
|
|
|
606
|
+
override updated(changedProperties: Map<string, any>) {
|
|
607
|
+
// Update the focused element if there is a change in bounds (otherwise Lit keeps focus on the relative element).
|
|
608
|
+
if (
|
|
609
|
+
this.focusActive &&
|
|
610
|
+
(changedProperties.has('visRowMin') || changedProperties.has('visColMin') || changedProperties.has('focusedCell'))
|
|
611
|
+
) {
|
|
612
|
+
this.refocus();
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
467
616
|
override disconnectedCallback() {
|
|
468
617
|
super.disconnectedCallback();
|
|
469
618
|
// console.log('[disconnected]', this.viewportRef.value);
|
package/src/index.ts
CHANGED
package/src/types.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
export type DxGridAxis = 'row' | 'col';
|
|
6
|
+
|
|
7
|
+
export type DxAxisResizeProps = Pick<DxAxisResize, 'axis' | 'index' | 'size'>;
|
|
8
|
+
|
|
9
|
+
export class DxAxisResize extends Event {
|
|
10
|
+
public readonly axis: DxGridAxis;
|
|
11
|
+
public readonly index: string;
|
|
12
|
+
public readonly size: number;
|
|
13
|
+
constructor(props: DxAxisResizeProps) {
|
|
14
|
+
super('dx-axis-resize');
|
|
15
|
+
this.axis = props.axis;
|
|
16
|
+
this.index = props.index;
|
|
17
|
+
this.size = props.size;
|
|
18
|
+
}
|
|
19
|
+
}
|