@dxos/lit-grid 0.6.10 → 0.6.11-staging.30cf5ba
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 +169 -16
- 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 -4
- 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,7 +1,19 @@
|
|
|
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
19
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
|
|
@@ -100,7 +112,15 @@ var DxGrid = class extends LitElement {
|
|
|
100
112
|
}
|
|
101
113
|
};
|
|
102
114
|
this.handlePointerUp = (_event) => {
|
|
103
|
-
this.resizing
|
|
115
|
+
if (this.resizing) {
|
|
116
|
+
const resizeEvent = new DxAxisResize({
|
|
117
|
+
axis: this.resizing.axis,
|
|
118
|
+
index: this.resizing.index,
|
|
119
|
+
size: this[this.resizing.axis === "col" ? "colSize" : "rowSize"](this.resizing.index)
|
|
120
|
+
});
|
|
121
|
+
this.dispatchEvent(resizeEvent);
|
|
122
|
+
this.resizing = null;
|
|
123
|
+
}
|
|
104
124
|
};
|
|
105
125
|
this.handlePointerMove = (event) => {
|
|
106
126
|
if (this.resizing) {
|
|
@@ -145,6 +165,12 @@ var DxGrid = class extends LitElement {
|
|
|
145
165
|
this.updateVis();
|
|
146
166
|
}
|
|
147
167
|
};
|
|
168
|
+
// Focus handlers
|
|
169
|
+
this.focusedCell = {
|
|
170
|
+
col: 0,
|
|
171
|
+
row: 0
|
|
172
|
+
};
|
|
173
|
+
this.focusActive = false;
|
|
148
174
|
}
|
|
149
175
|
//
|
|
150
176
|
// Accessors
|
|
@@ -174,11 +200,11 @@ var DxGrid = class extends LitElement {
|
|
|
174
200
|
acc += this.colSize(this.visColMin + c0);
|
|
175
201
|
return acc;
|
|
176
202
|
}, 0) + gap * (overscanCol - 1);
|
|
177
|
-
while (pxInline < this.binInlineMax + this.sizeInline) {
|
|
203
|
+
while (pxInline < this.binInlineMax + this.sizeInline + gap) {
|
|
178
204
|
colIndex += 1;
|
|
179
205
|
pxInline += this.colSize(colIndex) + gap;
|
|
180
206
|
}
|
|
181
|
-
this.visColMax = colIndex + overscanCol
|
|
207
|
+
this.visColMax = colIndex + overscanCol;
|
|
182
208
|
this.templateColumns = [
|
|
183
209
|
...Array(this.visColMax - this.visColMin)
|
|
184
210
|
].map((_, c0) => `${this.colSize(this.visColMin + c0)}px`).join(" ");
|
|
@@ -203,7 +229,7 @@ var DxGrid = class extends LitElement {
|
|
|
203
229
|
rowIndex += 1;
|
|
204
230
|
pxBlock += this.rowSize(rowIndex) + gap;
|
|
205
231
|
}
|
|
206
|
-
this.visRowMax = rowIndex + overscanRow
|
|
232
|
+
this.visRowMax = rowIndex + overscanRow;
|
|
207
233
|
this.templateRows = [
|
|
208
234
|
...Array(this.visRowMax - this.visRowMin)
|
|
209
235
|
].map((_, r0) => `${this.rowSize(this.visRowMin + r0)}px`).join(" ");
|
|
@@ -212,20 +238,124 @@ var DxGrid = class extends LitElement {
|
|
|
212
238
|
this.updateVisInline();
|
|
213
239
|
this.updateVisBlock();
|
|
214
240
|
}
|
|
241
|
+
handleFocus(event) {
|
|
242
|
+
const target = event.target;
|
|
243
|
+
const action = target.getAttribute("data-dx-grid-action");
|
|
244
|
+
if (action === "cell") {
|
|
245
|
+
const c = parseInt(target.getAttribute("aria-colindex") ?? "never");
|
|
246
|
+
const r = parseInt(target.getAttribute("aria-rowindex") ?? "never");
|
|
247
|
+
this.focusedCell = {
|
|
248
|
+
col: c,
|
|
249
|
+
row: r
|
|
250
|
+
};
|
|
251
|
+
this.focusActive = true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
handleBlur(event) {
|
|
255
|
+
if (!event.relatedTarget || event.relatedTarget.closest(".dx-grid__viewport") !== this.viewportRef.value) {
|
|
256
|
+
this.focusActive = false;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Moves focus to the cell with actual focus, otherwise moves focus to the viewport.
|
|
261
|
+
*/
|
|
262
|
+
refocus() {
|
|
263
|
+
(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({
|
|
264
|
+
preventScroll: true
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Updates `pos` so that a cell in focus is fully within the viewport
|
|
269
|
+
*/
|
|
270
|
+
snapPosToFocusedCell() {
|
|
271
|
+
if (this.focusedCell.col < this.visColMin || this.focusedCell.col > this.visColMax || this.focusedCell.row < this.visRowMin || this.focusedCell.row > this.visRowMax) {
|
|
272
|
+
} 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) {
|
|
273
|
+
} else {
|
|
274
|
+
if (this.focusedCell.col <= this.visColMin + overscanCol) {
|
|
275
|
+
this.posInline = this.binInlineMin;
|
|
276
|
+
this.updateVisInline();
|
|
277
|
+
} else if (this.focusedCell.col >= this.visColMax - overscanCol - 1) {
|
|
278
|
+
const sizeSumCol = [
|
|
279
|
+
...Array(this.focusedCell.col - this.visColMin)
|
|
280
|
+
].reduce((acc, _, c0) => {
|
|
281
|
+
acc += this.colSize(this.visColMin + overscanCol + c0) + gap;
|
|
282
|
+
return acc;
|
|
283
|
+
}, 0);
|
|
284
|
+
this.posInline = this.binInlineMin + sizeSumCol + gap * 2 - this.sizeInline;
|
|
285
|
+
this.updateVisInline();
|
|
286
|
+
}
|
|
287
|
+
if (this.focusedCell.row <= this.visRowMin + overscanRow) {
|
|
288
|
+
this.posBlock = this.binBlockMin;
|
|
289
|
+
this.updateVisBlock();
|
|
290
|
+
} else if (this.focusedCell.row >= this.visRowMax - overscanRow - 1) {
|
|
291
|
+
const sizeSumRow = [
|
|
292
|
+
...Array(this.focusedCell.row - this.visRowMin)
|
|
293
|
+
].reduce((acc, _, r0) => {
|
|
294
|
+
acc += this.rowSize(this.visRowMin + overscanRow + r0) + gap;
|
|
295
|
+
return acc;
|
|
296
|
+
}, 0);
|
|
297
|
+
this.posBlock = this.binBlockMin + sizeSumRow + gap * 2 - this.sizeBlock;
|
|
298
|
+
this.updateVisBlock();
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// Keyboard interactions
|
|
303
|
+
handleKeydown(event) {
|
|
304
|
+
if (this.focusActive) {
|
|
305
|
+
switch (event.key) {
|
|
306
|
+
case "ArrowDown":
|
|
307
|
+
this.focusedCell = {
|
|
308
|
+
...this.focusedCell,
|
|
309
|
+
row: this.focusedCell.row + 1
|
|
310
|
+
};
|
|
311
|
+
break;
|
|
312
|
+
case "ArrowUp":
|
|
313
|
+
this.focusedCell = {
|
|
314
|
+
...this.focusedCell,
|
|
315
|
+
row: Math.max(0, this.focusedCell.row - 1)
|
|
316
|
+
};
|
|
317
|
+
break;
|
|
318
|
+
case "ArrowRight":
|
|
319
|
+
this.focusedCell = {
|
|
320
|
+
...this.focusedCell,
|
|
321
|
+
col: this.focusedCell.col + 1
|
|
322
|
+
};
|
|
323
|
+
break;
|
|
324
|
+
case "ArrowLeft":
|
|
325
|
+
this.focusedCell = {
|
|
326
|
+
...this.focusedCell,
|
|
327
|
+
col: Math.max(0, this.focusedCell.col - 1)
|
|
328
|
+
};
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
switch (event.key) {
|
|
332
|
+
case "ArrowDown":
|
|
333
|
+
case "ArrowUp":
|
|
334
|
+
case "ArrowRight":
|
|
335
|
+
case "ArrowLeft":
|
|
336
|
+
event.preventDefault();
|
|
337
|
+
this.snapPosToFocusedCell();
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
215
342
|
//
|
|
216
343
|
// Render and other lifecycle methods
|
|
217
344
|
//
|
|
218
345
|
render() {
|
|
219
346
|
const visibleCols = this.visColMax - this.visColMin;
|
|
220
347
|
const visibleRows = this.visRowMax - this.visRowMin;
|
|
221
|
-
const offsetInline = this.binInlineMin - this.posInline - this.overscanInline;
|
|
222
|
-
const offsetBlock = this.binBlockMin - this.posBlock - this.overscanBlock;
|
|
348
|
+
const offsetInline = gap + this.binInlineMin - this.posInline - this.overscanInline;
|
|
349
|
+
const offsetBlock = gap + this.binBlockMin - this.posBlock - this.overscanBlock;
|
|
223
350
|
return html`<div
|
|
224
351
|
role="none"
|
|
225
352
|
class="dx-grid"
|
|
226
353
|
@pointerdown=${this.handlePointerDown}
|
|
227
354
|
@pointerup=${this.handlePointerUp}
|
|
228
355
|
@pointermove=${this.handlePointerMove}
|
|
356
|
+
@focus=${this.handleFocus}
|
|
357
|
+
@blur=${this.handleBlur}
|
|
358
|
+
@keydown=${this.handleKeydown}
|
|
229
359
|
>
|
|
230
360
|
<div role="none" class="dx-grid__corner"></div>
|
|
231
361
|
<div role="none" class="dx-grid__columnheader">
|
|
@@ -241,7 +371,7 @@ var DxGrid = class extends LitElement {
|
|
|
241
371
|
return html`<div
|
|
242
372
|
role="columnheader"
|
|
243
373
|
?inert=${c < 0}
|
|
244
|
-
style="
|
|
374
|
+
style="block-size:${this.rowDefault.size}px;grid-column:${c0 + 1}/${c0 + 2};"
|
|
245
375
|
>
|
|
246
376
|
<span id=${localChId(c0)}>${colToA1Notation(c)}</span>
|
|
247
377
|
${(this.columns[c]?.resizeable ?? this.columnDefault.resizeable) && html`<button class="dx-grid__resize-handle" data-dx-grid-action=${`resize-col,${c}`}>
|
|
@@ -253,16 +383,16 @@ var DxGrid = class extends LitElement {
|
|
|
253
383
|
</div>
|
|
254
384
|
<div role="none" class="dx-grid__corner"></div>
|
|
255
385
|
<div role="none" class="dx-grid__rowheader">
|
|
256
|
-
<div
|
|
386
|
+
<div
|
|
387
|
+
role="none"
|
|
388
|
+
class="dx-grid__rowheader__content"
|
|
389
|
+
style="transform:translate3d(0,${offsetBlock}px,0);grid-template-rows:${this.templateRows};"
|
|
390
|
+
>
|
|
257
391
|
${[
|
|
258
392
|
...Array(visibleRows)
|
|
259
393
|
].map((_, r0) => {
|
|
260
394
|
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
|
-
>
|
|
395
|
+
return html`<div role="rowheader" ?inert=${r < 0} style="grid-row:${r0 + 1}/${r0 + 2}">
|
|
266
396
|
<span id=${localRhId(r0)}>${rowToA1Notation(r)}</span>
|
|
267
397
|
${(this.rows[r]?.resizeable ?? this.rowDefault.resizeable) && html`<button class="dx-grid__resize-handle" data-dx-grid-action=${`resize-row,${r}`}>
|
|
268
398
|
<span class="sr-only">Resize</span>
|
|
@@ -271,9 +401,9 @@ var DxGrid = class extends LitElement {
|
|
|
271
401
|
})}
|
|
272
402
|
</div>
|
|
273
403
|
</div>
|
|
274
|
-
<div role="
|
|
404
|
+
<div role="grid" class="dx-grid__viewport" tabindex="0" @wheel=${this.handleWheel} ${ref(this.viewportRef)}>
|
|
275
405
|
<div
|
|
276
|
-
role="
|
|
406
|
+
role="none"
|
|
277
407
|
class="dx-grid__content"
|
|
278
408
|
style="transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this.templateColumns};grid-template-rows:${this.templateRows};"
|
|
279
409
|
>
|
|
@@ -288,6 +418,7 @@ var DxGrid = class extends LitElement {
|
|
|
288
418
|
const cell = this.getCell(c, r);
|
|
289
419
|
return html`<div
|
|
290
420
|
role="gridcell"
|
|
421
|
+
tabindex="0"
|
|
291
422
|
?inert=${c < 0 || r < 0}
|
|
292
423
|
aria-rowindex=${r}
|
|
293
424
|
aria-colindex=${c}
|
|
@@ -325,6 +456,11 @@ var DxGrid = class extends LitElement {
|
|
|
325
456
|
return acc;
|
|
326
457
|
}, {});
|
|
327
458
|
}
|
|
459
|
+
updated(changedProperties) {
|
|
460
|
+
if (this.focusActive && (changedProperties.has("visRowMin") || changedProperties.has("visColMin") || changedProperties.has("focusedCell"))) {
|
|
461
|
+
this.refocus();
|
|
462
|
+
}
|
|
463
|
+
}
|
|
328
464
|
disconnectedCallback() {
|
|
329
465
|
super.disconnectedCallback();
|
|
330
466
|
if (this.viewportRef.value) {
|
|
@@ -420,10 +556,27 @@ _ts_decorate([
|
|
|
420
556
|
_ts_decorate([
|
|
421
557
|
state()
|
|
422
558
|
], DxGrid.prototype, "observer", void 0);
|
|
559
|
+
_ts_decorate([
|
|
560
|
+
state()
|
|
561
|
+
], DxGrid.prototype, "focusedCell", void 0);
|
|
562
|
+
_ts_decorate([
|
|
563
|
+
state()
|
|
564
|
+
], DxGrid.prototype, "focusActive", void 0);
|
|
565
|
+
_ts_decorate([
|
|
566
|
+
eventOptions({
|
|
567
|
+
capture: true
|
|
568
|
+
})
|
|
569
|
+
], DxGrid.prototype, "handleFocus", null);
|
|
570
|
+
_ts_decorate([
|
|
571
|
+
eventOptions({
|
|
572
|
+
capture: true
|
|
573
|
+
})
|
|
574
|
+
], DxGrid.prototype, "handleBlur", null);
|
|
423
575
|
DxGrid = _ts_decorate([
|
|
424
576
|
customElement("dx-grid")
|
|
425
577
|
], DxGrid);
|
|
426
578
|
export {
|
|
579
|
+
DxAxisResize,
|
|
427
580
|
DxGrid
|
|
428
581
|
};
|
|
429
582
|
//# 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":33652},"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":18590},"packages/ui/lit-grid/src/types.ts":{"bytesInOutput":186},"packages/ui/lit-grid/src/index.ts":{"bytesInOutput":0}},"bytes":18965}}}
|
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/lit-grid",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.11-staging.30cf5ba",
|
|
4
4
|
"description": "A grid webcomponent using Lit",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"browser": "./dist/lib/browser/index.mjs",
|
|
12
12
|
"types": "./dist/types/src/index.d.ts"
|
|
13
|
-
}
|
|
14
|
-
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"types": "dist/types/src/index.d.ts",
|
|
16
|
+
"typesVersions": {
|
|
17
|
+
"*": {}
|
|
15
18
|
},
|
|
16
|
-
"main": "src/index.ts",
|
|
17
19
|
"files": [
|
|
18
20
|
"src",
|
|
19
21
|
"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
|
+
}
|