@dxos/lit-grid 0.8.4-main.c1de068 → 0.8.4-main.e098934
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/src/defs.d.ts +1 -0
- package/dist/src/defs.d.ts.map +1 -1
- package/dist/src/defs.js +1 -0
- package/dist/src/defs.js.map +1 -1
- package/dist/src/dx-grid-axis-resize-handle.d.ts.map +1 -1
- package/dist/src/dx-grid-axis-resize-handle.js +3 -5
- package/dist/src/dx-grid-axis-resize-handle.js.map +1 -1
- package/dist/src/dx-grid-multiselect-cell.d.ts.map +1 -1
- package/dist/src/dx-grid-multiselect-cell.js +2 -1
- package/dist/src/dx-grid-multiselect-cell.js.map +1 -1
- package/dist/src/dx-grid.d.ts +9 -5
- package/dist/src/dx-grid.d.ts.map +1 -1
- package/dist/src/dx-grid.js +181 -145
- package/dist/src/dx-grid.js.map +1 -1
- package/dist/src/dx-grid.lit-stories.js +15 -18
- package/dist/src/dx-grid.lit-stories.js.map +1 -1
- package/dist/src/playwright/dx-grid.spec.js.map +1 -1
- package/dist/src/testing/dx-grid-manager.d.ts.map +1 -1
- package/dist/src/testing/dx-grid-manager.js.map +1 -1
- package/dist/src/types.d.ts +7 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/util.d.ts +4 -1
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +11 -11
- package/dist/src/util.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/defs.ts +1 -0
- package/src/dx-grid-axis-resize-handle.pcss +6 -0
- package/src/dx-grid-axis-resize-handle.ts +1 -1
- package/src/dx-grid-multiselect-cell.ts +2 -1
- package/src/dx-grid.pcss +14 -1
- package/src/dx-grid.ts +172 -91
- package/src/playwright/dx-grid.spec.ts +1 -1
- package/src/testing/dx-grid-manager.ts +1 -1
- package/src/types.ts +7 -0
- package/src/util.ts +13 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/lit-grid",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.e098934",
|
|
4
4
|
"description": "A grid Web Component using Lit",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"lit": "^3.2.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@dxos/random": "0.8.4-main.
|
|
43
|
-
"@dxos/test-utils": "0.8.4-main.
|
|
42
|
+
"@dxos/random": "0.8.4-main.e098934",
|
|
43
|
+
"@dxos/test-utils": "0.8.4-main.e098934"
|
|
44
44
|
}
|
|
45
45
|
}
|
package/src/defs.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
|
|
6
6
|
import { disableNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview';
|
|
7
7
|
import { preventUnhandled } from '@atlaskit/pragmatic-drag-and-drop/prevent-unhandled';
|
|
8
8
|
import { type CleanupFn, type DragLocationHistory } from '@atlaskit/pragmatic-drag-and-drop/types';
|
|
9
|
-
import {
|
|
9
|
+
import { LitElement, html } from 'lit';
|
|
10
10
|
import { customElement, property } from 'lit/decorators.js';
|
|
11
11
|
import { ref } from 'lit/directives/ref.js';
|
|
12
12
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { LitElement, html } from 'lit';
|
|
6
6
|
import { customElement, property } from 'lit/decorators.js';
|
|
7
7
|
|
|
8
8
|
export type DxGridSelectValue = {
|
|
@@ -31,6 +31,7 @@ export class DxGridMultiselectCell extends LitElement {
|
|
|
31
31
|
aria-haspopup="dialog"
|
|
32
32
|
class="dx-grid__cell__multiselect"
|
|
33
33
|
data-dx-grid-accessory="invoke-multiselect"
|
|
34
|
+
data-dx-grid-action="accessory"
|
|
34
35
|
>
|
|
35
36
|
${this.values.length > 0
|
|
36
37
|
? this.values.map(({ label }) => html`<span class="dx-grid__cell__multiselect__value">${label}</span>`)
|
package/src/dx-grid.pcss
CHANGED
|
@@ -130,6 +130,18 @@
|
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
|
+
|
|
134
|
+
.dx-grid__row--cta__cell {
|
|
135
|
+
transition: background-color 100ms linear;
|
|
136
|
+
& > .dx-grid__cell__content {
|
|
137
|
+
cursor: pointer;
|
|
138
|
+
background: transparent !important;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
&:has(.dx-grid__row--cta__cell:hover) .dx-grid__row--cta__cell {
|
|
143
|
+
background: var(--dx-hoverOverlay);
|
|
144
|
+
}
|
|
133
145
|
}
|
|
134
146
|
|
|
135
147
|
/* Editor and focused cell styles; be sure to keep these two blocks in-sync. */
|
|
@@ -137,7 +149,7 @@
|
|
|
137
149
|
[role='gridcell'],
|
|
138
150
|
[role='columnheader'],
|
|
139
151
|
[role='rowheader'] {
|
|
140
|
-
&:not(.dx-grid__cell--no-focus-unfurl){
|
|
152
|
+
&:not([data-focus-unfurl="false"]):not(.dx-grid__cell--no-focus-unfurl) {
|
|
141
153
|
&:focus,
|
|
142
154
|
&:focus-within {
|
|
143
155
|
& > .dx-grid__cell__content {
|
|
@@ -235,6 +247,7 @@
|
|
|
235
247
|
block-size: 0;
|
|
236
248
|
border-inline-start: 0.5em solid transparent;
|
|
237
249
|
border-block-start: 0.5em solid var(--dx-warningText);
|
|
250
|
+
z-index: 1;
|
|
238
251
|
}
|
|
239
252
|
}
|
|
240
253
|
}
|
package/src/dx-grid.ts
CHANGED
|
@@ -3,23 +3,23 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { LitElement, html, nothing } from 'lit';
|
|
6
|
-
import { customElement,
|
|
7
|
-
import {
|
|
6
|
+
import { customElement, property, state } from 'lit/decorators.js';
|
|
7
|
+
import { type Ref, createRef, ref } from 'lit/directives/ref.js';
|
|
8
8
|
import { styleMap } from 'lit/directives/style-map.js';
|
|
9
|
-
import {
|
|
9
|
+
import { html as staticHtml, unsafeStatic } from 'lit/static-html.js';
|
|
10
10
|
|
|
11
|
-
import { defaultColSize, defaultRowSize } from './defs';
|
|
12
|
-
// eslint-disable-next-line unused-imports/no-unused-imports
|
|
11
|
+
import { defaultColSize, defaultRowSize, focusUnfurlDefault } from './defs';
|
|
13
12
|
import './dx-grid-axis-resize-handle';
|
|
14
13
|
import {
|
|
15
|
-
type DxGridAxisMetaProps,
|
|
16
|
-
type DxGridAxisSizes,
|
|
17
|
-
type DxGridPlaneCellIndex,
|
|
18
|
-
type DxGridCellValue,
|
|
19
14
|
DxAxisResize,
|
|
20
15
|
type DxAxisResizeInternal,
|
|
21
16
|
DxEditRequest,
|
|
17
|
+
type DxGridAnnotatedPanEvent,
|
|
18
|
+
type DxGridAxis,
|
|
22
19
|
type DxGridAxisMeta,
|
|
20
|
+
type DxGridAxisMetaProps,
|
|
21
|
+
type DxGridAxisSizes,
|
|
22
|
+
type DxGridCellValue,
|
|
23
23
|
type DxGridCells,
|
|
24
24
|
DxGridCellsSelect,
|
|
25
25
|
type DxGridFixedPlane,
|
|
@@ -29,36 +29,35 @@ import {
|
|
|
29
29
|
type DxGridFrozenRowsPlane,
|
|
30
30
|
type DxGridMode,
|
|
31
31
|
type DxGridPlane,
|
|
32
|
+
type DxGridPlaneCellIndex,
|
|
32
33
|
type DxGridPlaneCells,
|
|
33
34
|
type DxGridPlaneRange,
|
|
34
35
|
type DxGridPlaneRecord,
|
|
35
36
|
type DxGridPointer,
|
|
36
37
|
type DxGridPosition,
|
|
37
|
-
type DxGridAxis,
|
|
38
|
-
type DxGridSelectionProps,
|
|
39
|
-
type DxGridAnnotatedPanEvent,
|
|
40
38
|
type DxGridRange,
|
|
39
|
+
type DxGridSelectionProps,
|
|
41
40
|
separator,
|
|
42
41
|
} from './types';
|
|
43
42
|
import {
|
|
44
|
-
toCellIndex,
|
|
45
|
-
gap,
|
|
46
|
-
resizeTolerance,
|
|
47
|
-
sizeColMin,
|
|
48
|
-
sizeColMax,
|
|
49
|
-
sizeRowMin,
|
|
50
|
-
sizeRowMax,
|
|
51
|
-
shouldSelect,
|
|
52
|
-
selectionProps,
|
|
53
43
|
cellSelected,
|
|
54
44
|
closestAction,
|
|
55
45
|
closestCell,
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
gap,
|
|
47
|
+
isReadonly,
|
|
48
|
+
isSameCell,
|
|
49
|
+
resizeTolerance,
|
|
58
50
|
resolveColPlane,
|
|
59
51
|
resolveFrozenPlane,
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
resolveRowPlane,
|
|
53
|
+
selectionProps,
|
|
54
|
+
shouldSelect,
|
|
55
|
+
sizeColMax,
|
|
56
|
+
sizeColMin,
|
|
57
|
+
sizeRowMax,
|
|
58
|
+
sizeRowMin,
|
|
59
|
+
targetIsPlane,
|
|
60
|
+
toCellIndex,
|
|
62
61
|
} from './util';
|
|
63
62
|
|
|
64
63
|
@customElement('dx-grid')
|
|
@@ -84,12 +83,12 @@ export class DxGrid extends LitElement {
|
|
|
84
83
|
gridId: string = 'default-grid-id';
|
|
85
84
|
|
|
86
85
|
@property({ type: Object })
|
|
87
|
-
rowDefault: DxGridPlaneRecord<DxGridFrozenRowsPlane, DxGridAxisMetaProps
|
|
86
|
+
rowDefault: Partial<DxGridPlaneRecord<DxGridFrozenRowsPlane, Partial<DxGridAxisMetaProps>>> = {
|
|
88
87
|
grid: { size: defaultRowSize },
|
|
89
88
|
};
|
|
90
89
|
|
|
91
90
|
@property({ type: Object })
|
|
92
|
-
columnDefault: DxGridPlaneRecord<DxGridFrozenColsPlane, DxGridAxisMetaProps
|
|
91
|
+
columnDefault: Partial<DxGridPlaneRecord<DxGridFrozenColsPlane, Partial<DxGridAxisMetaProps>>> = {
|
|
93
92
|
grid: { size: defaultColSize },
|
|
94
93
|
};
|
|
95
94
|
|
|
@@ -213,6 +212,16 @@ export class DxGrid extends LitElement {
|
|
|
213
212
|
@state()
|
|
214
213
|
private templatefrozenRowsEnd = '';
|
|
215
214
|
|
|
215
|
+
//
|
|
216
|
+
// `frozen…Size` is used to measure space available for the non-fixed planes
|
|
217
|
+
//
|
|
218
|
+
|
|
219
|
+
@state()
|
|
220
|
+
private frozenColsSize = 0;
|
|
221
|
+
|
|
222
|
+
@state()
|
|
223
|
+
private frozenRowsSize = 0;
|
|
224
|
+
|
|
216
225
|
//
|
|
217
226
|
// Focus, selection, and resize states
|
|
218
227
|
//
|
|
@@ -481,6 +490,13 @@ export class DxGrid extends LitElement {
|
|
|
481
490
|
event.preventDefault();
|
|
482
491
|
this.dispatchEditRequest();
|
|
483
492
|
break;
|
|
493
|
+
case 'Backspace':
|
|
494
|
+
case 'Delete':
|
|
495
|
+
if (!event.defaultPrevented) {
|
|
496
|
+
event.preventDefault();
|
|
497
|
+
this.dispatchEditRequest('');
|
|
498
|
+
}
|
|
499
|
+
break;
|
|
484
500
|
default:
|
|
485
501
|
if (event.key.length === 1 && event.key.match(/\P{Cc}/u) && !(event.metaKey || event.ctrlKey)) {
|
|
486
502
|
this.dispatchEditRequest(event.key);
|
|
@@ -584,19 +600,18 @@ export class DxGrid extends LitElement {
|
|
|
584
600
|
blockSize: 0,
|
|
585
601
|
};
|
|
586
602
|
if (
|
|
587
|
-
Math.abs(inlineSize - this.sizeInline) > resizeTolerance ||
|
|
588
|
-
Math.abs(blockSize - this.sizeBlock) > resizeTolerance
|
|
603
|
+
Math.abs(inlineSize - this.frozenColsSize - this.sizeInline) > resizeTolerance ||
|
|
604
|
+
Math.abs(blockSize - this.frozenRowsSize - this.sizeBlock) > resizeTolerance
|
|
589
605
|
) {
|
|
590
606
|
// console.info('[updating bounds]', 'resize', [inlineSize - this.sizeInline, blockSize - this.sizeBlock]);
|
|
591
|
-
this.sizeInline = inlineSize;
|
|
592
|
-
this.sizeBlock = blockSize;
|
|
607
|
+
this.sizeInline = inlineSize - this.frozenColsSize;
|
|
608
|
+
this.sizeBlock = blockSize - this.frozenRowsSize;
|
|
593
609
|
this.updateVis();
|
|
594
610
|
queueMicrotask(() => this.updatePos());
|
|
595
611
|
}
|
|
596
612
|
});
|
|
597
613
|
|
|
598
614
|
private gridRef: Ref<HTMLDivElement> = createRef();
|
|
599
|
-
private viewportRef: Ref<HTMLDivElement> = createRef();
|
|
600
615
|
|
|
601
616
|
private maybeUpdateVisInline = () => {
|
|
602
617
|
if (this.posInline < this.binInlineMin || this.posInline >= this.binInlineMax) {
|
|
@@ -721,6 +736,15 @@ export class DxGrid extends LitElement {
|
|
|
721
736
|
this.templatefrozenColsEnd = [...Array(this.frozen.frozenColsEnd ?? 0)]
|
|
722
737
|
.map((_, c0) => `${this.colSize(c0, 'frozenColsEnd')}px`)
|
|
723
738
|
.join(' ');
|
|
739
|
+
|
|
740
|
+
this.frozenColsSize =
|
|
741
|
+
[...Array(this.frozen.frozenColsStart ?? 0)].reduce(
|
|
742
|
+
(sum, _, c0) => sum + this.colSize(c0, 'frozenColsStart'),
|
|
743
|
+
0,
|
|
744
|
+
) +
|
|
745
|
+
gap * Math.max(0, this.frozen.frozenColsStart ?? 0 - 1) +
|
|
746
|
+
[...Array(this.frozen.frozenColsEnd ?? 0)].reduce((sum, _, c0) => sum + this.colSize(c0, 'frozenColsEnd'), 0) +
|
|
747
|
+
gap * Math.max(0, this.frozen.frozenColsEnd ?? 0 - 1);
|
|
724
748
|
}
|
|
725
749
|
|
|
726
750
|
private updateVisBlock(): void {
|
|
@@ -770,6 +794,15 @@ export class DxGrid extends LitElement {
|
|
|
770
794
|
this.templatefrozenRowsEnd = [...Array(this.frozen.frozenRowsEnd ?? 0)]
|
|
771
795
|
.map((_, r0) => `${this.rowSize(r0, 'frozenRowsEnd')}px`)
|
|
772
796
|
.join(' ');
|
|
797
|
+
|
|
798
|
+
this.frozenRowsSize =
|
|
799
|
+
[...Array(this.frozen.frozenRowsStart ?? 0)].reduce(
|
|
800
|
+
(sum, _, r0) => sum + this.rowSize(r0, 'frozenRowsStart'),
|
|
801
|
+
0,
|
|
802
|
+
) +
|
|
803
|
+
gap * Math.max(0, this.frozen.frozenRowsStart ?? 0 - 1) +
|
|
804
|
+
[...Array(this.frozen.frozenRowsEnd ?? 0)].reduce((sum, _, r0) => sum + this.rowSize(r0, 'frozenRowsEnd'), 0) +
|
|
805
|
+
gap * Math.max(0, this.frozen.frozenRowsEnd ?? 0 - 1);
|
|
773
806
|
}
|
|
774
807
|
|
|
775
808
|
private updateVis(): void {
|
|
@@ -1068,16 +1101,40 @@ export class DxGrid extends LitElement {
|
|
|
1068
1101
|
: !!(this.rows[plane]?.[index]?.resizeable ?? this.rowDefault[plane as DxGridFrozenRowsPlane]?.resizeable);
|
|
1069
1102
|
}
|
|
1070
1103
|
|
|
1104
|
+
private clampAxisSize(
|
|
1105
|
+
plane: 'grid' | DxGridFrozenPlane,
|
|
1106
|
+
axis: DxGridAxis,
|
|
1107
|
+
index: number | string,
|
|
1108
|
+
requestedSize: number,
|
|
1109
|
+
): number {
|
|
1110
|
+
const minSize =
|
|
1111
|
+
axis === 'col'
|
|
1112
|
+
? (this.columns[plane]?.[index]?.minSize ??
|
|
1113
|
+
this.columnDefault[plane as DxGridFrozenColsPlane]?.minSize ??
|
|
1114
|
+
sizeColMin)
|
|
1115
|
+
: (this.rows[plane]?.[index]?.minSize ??
|
|
1116
|
+
this.rowDefault[plane as DxGridFrozenRowsPlane]?.minSize ??
|
|
1117
|
+
sizeRowMin);
|
|
1118
|
+
const maxSize =
|
|
1119
|
+
axis === 'col'
|
|
1120
|
+
? (this.columns[plane]?.[index]?.maxSize ??
|
|
1121
|
+
this.columnDefault[plane as DxGridFrozenColsPlane]?.maxSize ??
|
|
1122
|
+
sizeColMax)
|
|
1123
|
+
: (this.rows[plane]?.[index]?.maxSize ??
|
|
1124
|
+
this.rowDefault[plane as DxGridFrozenRowsPlane]?.maxSize ??
|
|
1125
|
+
sizeRowMax);
|
|
1126
|
+
return Math.max(minSize, Math.min(maxSize, requestedSize));
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1071
1129
|
private handleAxisResizeInternal(event: DxAxisResizeInternal): void {
|
|
1072
1130
|
event.stopPropagation();
|
|
1073
1131
|
const { plane, axis, delta, size, index, state } = event;
|
|
1132
|
+
const nextSize = this.clampAxisSize(plane, axis, index, size + delta);
|
|
1074
1133
|
if (axis === 'col') {
|
|
1075
|
-
const nextSize = Math.max(sizeColMin, Math.min(sizeColMax, size + delta));
|
|
1076
1134
|
this.colSizes = { ...this.colSizes, [plane]: { ...this.colSizes[plane], [index]: nextSize } };
|
|
1077
1135
|
this.updateVisInline();
|
|
1078
1136
|
this.updateIntrinsicInlineSize();
|
|
1079
1137
|
} else {
|
|
1080
|
-
const nextSize = Math.max(sizeRowMin, Math.min(sizeRowMax, size + delta));
|
|
1081
1138
|
this.rowSizes = { ...this.colSizes, [plane]: { ...this.rowSizes[plane], [index]: nextSize } };
|
|
1082
1139
|
this.updateVisBlock();
|
|
1083
1140
|
this.updateIntrinsicBlockSize();
|
|
@@ -1178,7 +1235,7 @@ export class DxGrid extends LitElement {
|
|
|
1178
1235
|
) {
|
|
1179
1236
|
const rowPlane = resolveRowPlane(plane) as DxGridFrozenPlane;
|
|
1180
1237
|
const rows = this.frozen[rowPlane];
|
|
1181
|
-
return (rows ?? 0) > 0
|
|
1238
|
+
return (rows ?? 0) > 0 && this.limitColumns > 0
|
|
1182
1239
|
? html`<div
|
|
1183
1240
|
role="none"
|
|
1184
1241
|
class="dx-grid__plane--frozen-row"
|
|
@@ -1212,7 +1269,7 @@ export class DxGrid extends LitElement {
|
|
|
1212
1269
|
) {
|
|
1213
1270
|
const colPlane = resolveColPlane(plane) as DxGridFrozenPlane;
|
|
1214
1271
|
const cols = this.frozen[colPlane];
|
|
1215
|
-
return (cols ?? 0) > 0
|
|
1272
|
+
return (cols ?? 0) > 0 && this.limitRows > 0
|
|
1216
1273
|
? html`<div
|
|
1217
1274
|
role="none"
|
|
1218
1275
|
class="dx-grid__plane--frozen-col"
|
|
@@ -1238,6 +1295,40 @@ export class DxGrid extends LitElement {
|
|
|
1238
1295
|
: null;
|
|
1239
1296
|
}
|
|
1240
1297
|
|
|
1298
|
+
private renderMainGrid(
|
|
1299
|
+
visibleCols: number,
|
|
1300
|
+
visibleRows: number,
|
|
1301
|
+
offsetInline: number,
|
|
1302
|
+
offsetBlock: number,
|
|
1303
|
+
selection: DxGridSelectionProps,
|
|
1304
|
+
) {
|
|
1305
|
+
return this.limitRows > 0 && this.limitColumns > 0
|
|
1306
|
+
? html`<div
|
|
1307
|
+
role="grid"
|
|
1308
|
+
class="dx-grid__plane--grid"
|
|
1309
|
+
tabindex="0"
|
|
1310
|
+
data-dx-grid-plane="grid"
|
|
1311
|
+
data-dx-grid-plane-row="1"
|
|
1312
|
+
data-dx-grid-plane-col="1"
|
|
1313
|
+
>
|
|
1314
|
+
<div
|
|
1315
|
+
role="none"
|
|
1316
|
+
class="dx-grid__plane--grid__content"
|
|
1317
|
+
style="transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this
|
|
1318
|
+
.templateGridColumns};grid-template-rows:${this.templateGridRows};"
|
|
1319
|
+
>
|
|
1320
|
+
${[...Array(visibleRows)].map((_, r0) => {
|
|
1321
|
+
return [...Array(visibleCols)].map((_, c0) => {
|
|
1322
|
+
const c = c0 + this.visColMin;
|
|
1323
|
+
const r = r0 + this.visRowMin;
|
|
1324
|
+
return this.renderCell(c, r, 'grid', cellSelected(c, r, 'grid', selection), c0, r0);
|
|
1325
|
+
});
|
|
1326
|
+
})}
|
|
1327
|
+
</div>
|
|
1328
|
+
</div>`
|
|
1329
|
+
: null;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1241
1332
|
private cellReadonly(col: number, row: number, plane: DxGridPlane): boolean {
|
|
1242
1333
|
const colPlane = resolveColPlane(plane);
|
|
1243
1334
|
const rowPlane = resolveRowPlane(plane);
|
|
@@ -1255,6 +1346,23 @@ export class DxGrid extends LitElement {
|
|
|
1255
1346
|
return isReadonly(colReadOnly) || isReadonly(rowReadOnly);
|
|
1256
1347
|
}
|
|
1257
1348
|
|
|
1349
|
+
private cellFocusUnfurl(col: number, row: number, plane: DxGridPlane): boolean {
|
|
1350
|
+
const colPlane = resolveColPlane(plane);
|
|
1351
|
+
const rowPlane = resolveRowPlane(plane);
|
|
1352
|
+
|
|
1353
|
+
// Check cell-specific setting first.
|
|
1354
|
+
const cellUnfurl = this.cell(col, row, plane)?.focusUnfurl;
|
|
1355
|
+
if (cellUnfurl !== undefined) {
|
|
1356
|
+
return cellUnfurl;
|
|
1357
|
+
}
|
|
1358
|
+
|
|
1359
|
+
// Check column/row defaults.
|
|
1360
|
+
const colUnfurl = this.columns?.[colPlane]?.[col]?.focusUnfurl ?? this.columnDefault?.[colPlane]?.focusUnfurl;
|
|
1361
|
+
const rowUnfurl = this.rows?.[rowPlane]?.[row]?.focusUnfurl ?? this.rowDefault?.[rowPlane]?.focusUnfurl;
|
|
1362
|
+
|
|
1363
|
+
return colUnfurl ?? rowUnfurl ?? focusUnfurlDefault;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1258
1366
|
/**
|
|
1259
1367
|
* Determines if the cell's text content should be selectable based on its readonly value.
|
|
1260
1368
|
* @returns true if the cells text content is selectable, false otherwise.
|
|
@@ -1317,6 +1425,7 @@ export class DxGrid extends LitElement {
|
|
|
1317
1425
|
const cell = this.cell(col, row, plane);
|
|
1318
1426
|
const active = this.cellActive(col, row, plane);
|
|
1319
1427
|
const readonly = this.cellReadonly(col, row, plane);
|
|
1428
|
+
const focusUnfurl = this.cellFocusUnfurl(col, row, plane);
|
|
1320
1429
|
const textSelectable = this.cellTextSelectable(col, row, plane);
|
|
1321
1430
|
const resizeIndex = cell?.resizeHandle ? (cell.resizeHandle === 'col' ? col : row) : undefined;
|
|
1322
1431
|
const resizePlane = cell?.resizeHandle ? resolveFrozenPlane(cell.resizeHandle, plane) : undefined;
|
|
@@ -1328,6 +1437,7 @@ export class DxGrid extends LitElement {
|
|
|
1328
1437
|
aria-readonly=${readonly ? 'true' : nothing}
|
|
1329
1438
|
class=${cell?.className ?? nothing}
|
|
1330
1439
|
data-refs=${cell?.dataRefs ?? nothing}
|
|
1440
|
+
data-focus-unfurl=${focusUnfurl ? nothing : 'false'}
|
|
1331
1441
|
?data-dx-active=${active}
|
|
1332
1442
|
data-text-selectable=${textSelectable ? 'true' : 'false'}
|
|
1333
1443
|
data-dx-grid-action="cell"
|
|
@@ -1370,13 +1480,24 @@ export class DxGrid extends LitElement {
|
|
|
1370
1480
|
<div
|
|
1371
1481
|
role="none"
|
|
1372
1482
|
class="dx-grid"
|
|
1483
|
+
data-arrow-keys="all"
|
|
1373
1484
|
style=${styleMap({
|
|
1374
|
-
'grid-template-columns':
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1485
|
+
'grid-template-columns': [
|
|
1486
|
+
this.templatefrozenColsStart ? 'min-content' : false,
|
|
1487
|
+
this.limitColumns > 0 &&
|
|
1488
|
+
`minmax(0, ${Number.isFinite(this.limitColumns) ? `${Math.max(0, this.intrinsicInlineSize)}px` : '1fr'})`,
|
|
1489
|
+
this.templatefrozenColsEnd ? 'min-content' : false,
|
|
1490
|
+
]
|
|
1491
|
+
.filter(Boolean)
|
|
1492
|
+
.join(' '),
|
|
1493
|
+
'grid-template-rows': [
|
|
1494
|
+
this.templatefrozenRowsStart ? 'min-content' : false,
|
|
1495
|
+
this.limitRows > 0 &&
|
|
1496
|
+
`minmax(0, ${Number.isFinite(this.limitRows) ? `${Math.max(0, this.intrinsicBlockSize)}px` : '1fr'})`,
|
|
1497
|
+
this.templatefrozenRowsEnd ? ' min-content' : false,
|
|
1498
|
+
]
|
|
1499
|
+
.filter(Boolean)
|
|
1500
|
+
.join(' '),
|
|
1380
1501
|
'--dx-grid-content-inline-size': Number.isFinite(this.limitColumns)
|
|
1381
1502
|
? `${Math.max(0, this.totalIntrinsicInlineSize)}px`
|
|
1382
1503
|
: 'max-content',
|
|
@@ -1400,30 +1521,7 @@ export class DxGrid extends LitElement {
|
|
|
1400
1521
|
offsetBlock,
|
|
1401
1522
|
selection,
|
|
1402
1523
|
)}
|
|
1403
|
-
|
|
1404
|
-
role="grid"
|
|
1405
|
-
class="dx-grid__plane--grid"
|
|
1406
|
-
tabindex="0"
|
|
1407
|
-
data-dx-grid-plane="grid"
|
|
1408
|
-
data-dx-grid-plane-row="1"
|
|
1409
|
-
data-dx-grid-plane-col="1"
|
|
1410
|
-
${ref(this.viewportRef)}
|
|
1411
|
-
>
|
|
1412
|
-
<div
|
|
1413
|
-
role="none"
|
|
1414
|
-
class="dx-grid__plane--grid__content"
|
|
1415
|
-
style="transform:translate3d(${offsetInline}px,${offsetBlock}px,0);grid-template-columns:${this
|
|
1416
|
-
.templateGridColumns};grid-template-rows:${this.templateGridRows};"
|
|
1417
|
-
>
|
|
1418
|
-
${[...Array(visibleRows)].map((_, r0) => {
|
|
1419
|
-
return [...Array(visibleCols)].map((_, c0) => {
|
|
1420
|
-
const c = c0 + this.visColMin;
|
|
1421
|
-
const r = r0 + this.visRowMin;
|
|
1422
|
-
return this.renderCell(c, r, 'grid', cellSelected(c, r, 'grid', selection), c0, r0);
|
|
1423
|
-
});
|
|
1424
|
-
})}
|
|
1425
|
-
</div>
|
|
1426
|
-
</div>
|
|
1524
|
+
${this.renderMainGrid(visibleCols, visibleRows, offsetInline, offsetBlock, selection)}
|
|
1427
1525
|
${this.renderFrozenColumns('frozenColsEnd', visibleRows, offsetBlock, selection)}${this.renderFixed(
|
|
1428
1526
|
'fixedEndStart',
|
|
1429
1527
|
selection,
|
|
@@ -1437,37 +1535,19 @@ export class DxGrid extends LitElement {
|
|
|
1437
1535
|
private updateIntrinsicInlineSize(): void {
|
|
1438
1536
|
this.intrinsicInlineSize = Number.isFinite(this.limitColumns)
|
|
1439
1537
|
? [...Array(this.limitColumns)].reduce((acc, _, c0) => acc + this.colSize(c0, 'grid'), 0) +
|
|
1440
|
-
gap * (this.limitColumns - 1)
|
|
1538
|
+
gap * Math.max(0, this.limitColumns - 1)
|
|
1441
1539
|
: Infinity;
|
|
1442
1540
|
this.totalIntrinsicInlineSize =
|
|
1443
|
-
this.intrinsicInlineSize +
|
|
1444
|
-
(Number.isFinite(this.frozen.frozenColsStart)
|
|
1445
|
-
? [...Array(this.frozen.frozenColsStart)].reduce(
|
|
1446
|
-
(acc, _, c0) => acc + gap + this.colSize(c0, 'frozenColsStart'),
|
|
1447
|
-
0,
|
|
1448
|
-
)
|
|
1449
|
-
: 0) +
|
|
1450
|
-
(Number.isFinite(this.frozen.frozenColsEnd)
|
|
1451
|
-
? [...Array(this.frozen.frozenColsEnd)].reduce((acc, _, c0) => acc + gap + this.colSize(c0, 'frozenColsEnd'), 0)
|
|
1452
|
-
: 0);
|
|
1541
|
+
this.limitColumns > 0 ? this.intrinsicInlineSize + this.frozenColsSize : this.frozenColsSize - gap;
|
|
1453
1542
|
}
|
|
1454
1543
|
|
|
1455
1544
|
private updateIntrinsicBlockSize(): void {
|
|
1456
1545
|
this.intrinsicBlockSize = Number.isFinite(this.limitRows)
|
|
1457
1546
|
? [...Array(this.limitRows)].reduce((acc, _, r0) => acc + this.rowSize(r0, 'grid'), 0) +
|
|
1458
|
-
gap * (this.limitRows - 1)
|
|
1547
|
+
gap * Math.max(0, this.limitRows - 1)
|
|
1459
1548
|
: Infinity;
|
|
1460
1549
|
this.totalIntrinsicBlockSize =
|
|
1461
|
-
this.intrinsicBlockSize +
|
|
1462
|
-
(Number.isFinite(this.frozen.frozenRowsStart)
|
|
1463
|
-
? [...Array(this.frozen.frozenRowsStart)].reduce(
|
|
1464
|
-
(acc, _, r0) => acc + gap + this.rowSize(r0, 'frozenRowsStart'),
|
|
1465
|
-
0,
|
|
1466
|
-
)
|
|
1467
|
-
: 0) +
|
|
1468
|
-
(Number.isFinite(this.frozen.frozenRowsEnd)
|
|
1469
|
-
? [...Array(this.frozen.frozenRowsEnd)].reduce((acc, _, r0) => acc + gap + this.rowSize(r0, 'frozenRowsEnd'), 0)
|
|
1470
|
-
: 0);
|
|
1550
|
+
this.limitRows > 0 ? this.intrinsicBlockSize + this.frozenRowsSize : this.frozenRowsSize - gap;
|
|
1471
1551
|
}
|
|
1472
1552
|
|
|
1473
1553
|
private updateIntrinsicSizes(): void {
|
|
@@ -1515,7 +1595,7 @@ export class DxGrid extends LitElement {
|
|
|
1515
1595
|
if (this.getCells) {
|
|
1516
1596
|
this.updateCells(true);
|
|
1517
1597
|
}
|
|
1518
|
-
this.observer.observe(this.
|
|
1598
|
+
this.observer.observe(this.gridRef.value!);
|
|
1519
1599
|
this.computeColSizes();
|
|
1520
1600
|
this.computeRowSizes();
|
|
1521
1601
|
this.updateIntrinsicSizes();
|
|
@@ -1589,8 +1669,8 @@ export class DxGrid extends LitElement {
|
|
|
1589
1669
|
|
|
1590
1670
|
override disconnectedCallback(): void {
|
|
1591
1671
|
super.disconnectedCallback();
|
|
1592
|
-
if (this.
|
|
1593
|
-
this.observer.unobserve(this.
|
|
1672
|
+
if (this.gridRef.value) {
|
|
1673
|
+
this.observer.unobserve(this.gridRef.value);
|
|
1594
1674
|
}
|
|
1595
1675
|
document.defaultView?.removeEventListener('wheel', this.handleTopLevelWheel);
|
|
1596
1676
|
}
|
|
@@ -1608,6 +1688,7 @@ export {
|
|
|
1608
1688
|
parseCellIndex,
|
|
1609
1689
|
toPlaneCellIndex,
|
|
1610
1690
|
cellQuery,
|
|
1691
|
+
accessoryHandlesPointerdownAttrs,
|
|
1611
1692
|
} from './util';
|
|
1612
1693
|
|
|
1613
1694
|
export const commentedClassName = 'dx-grid__cell--commented';
|
package/src/types.ts
CHANGED
|
@@ -83,6 +83,10 @@ export type DxGridCellValue = {
|
|
|
83
83
|
* Controls the read-only state of the cell.
|
|
84
84
|
*/
|
|
85
85
|
readonly?: DxGridReadonlyValue;
|
|
86
|
+
/**
|
|
87
|
+
* Controls whether the cell content should unfurl when the cell has focus.
|
|
88
|
+
*/
|
|
89
|
+
focusUnfurl?: boolean;
|
|
86
90
|
};
|
|
87
91
|
|
|
88
92
|
export type DxGridAxisMetaProps = {
|
|
@@ -90,6 +94,9 @@ export type DxGridAxisMetaProps = {
|
|
|
90
94
|
description?: string;
|
|
91
95
|
resizeable?: boolean;
|
|
92
96
|
readonly?: DxGridReadonlyValue;
|
|
97
|
+
focusUnfurl?: boolean;
|
|
98
|
+
minSize?: number;
|
|
99
|
+
maxSize?: number;
|
|
93
100
|
};
|
|
94
101
|
|
|
95
102
|
export type DxGridAxisSizes = DxGridPlaneRecord<DxGridFrozenPlane, Record<string, number>>;
|
package/src/util.ts
CHANGED
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
import { defaultRowSize } from './defs';
|
|
6
6
|
import {
|
|
7
|
-
type
|
|
7
|
+
type DxGridAxis,
|
|
8
8
|
type DxGridCellIndex,
|
|
9
|
-
type DxGridPosition,
|
|
10
|
-
type DxGridPointer,
|
|
11
|
-
type DxGridSelectionProps,
|
|
12
|
-
type DxGridPositionNullable,
|
|
13
|
-
type DxGridPlane,
|
|
14
|
-
type DxGridFrozenRowsPlane,
|
|
15
9
|
type DxGridFrozenColsPlane,
|
|
16
10
|
type DxGridFrozenPlane,
|
|
17
|
-
type
|
|
11
|
+
type DxGridFrozenRowsPlane,
|
|
12
|
+
type DxGridPlane,
|
|
13
|
+
type DxGridPlaneCellIndex,
|
|
18
14
|
type DxGridPlanePosition,
|
|
15
|
+
type DxGridPointer,
|
|
16
|
+
type DxGridPosition,
|
|
17
|
+
type DxGridPositionNullable,
|
|
19
18
|
type DxGridReadonlyValue,
|
|
19
|
+
type DxGridSelectionProps,
|
|
20
20
|
separator,
|
|
21
21
|
} from './types';
|
|
22
22
|
|
|
@@ -25,7 +25,7 @@ export const toPlaneCellIndex = (cellCoords: Partial<DxGridPosition> & DxGridPla
|
|
|
25
25
|
|
|
26
26
|
export function parseCellIndex(index: DxGridCellIndex): DxGridPosition;
|
|
27
27
|
export function parseCellIndex(index: DxGridPlaneCellIndex): DxGridPlanePosition;
|
|
28
|
-
|
|
28
|
+
|
|
29
29
|
export function parseCellIndex(index: DxGridPlaneCellIndex | DxGridCellIndex): DxGridPlanePosition | DxGridPosition {
|
|
30
30
|
const coords = index.split(separator);
|
|
31
31
|
if (coords.length === 3) {
|
|
@@ -123,6 +123,10 @@ export const closestAction = (target: EventTarget | null): { action: string | nu
|
|
|
123
123
|
return { actionEl, action: actionEl?.getAttribute('data-dx-grid-action') ?? null };
|
|
124
124
|
};
|
|
125
125
|
|
|
126
|
+
export const accessoryHandlesPointerdownAttrs = {
|
|
127
|
+
'data-dx-grid-action': 'accessory',
|
|
128
|
+
};
|
|
129
|
+
|
|
126
130
|
export const closestCell = (target: EventTarget | null, actionEl?: HTMLElement | null): DxGridPositionNullable => {
|
|
127
131
|
let cellElement = actionEl;
|
|
128
132
|
if (!cellElement) {
|