@vaadin/grid-pro 24.4.0-alpha9 → 24.4.0-beta2

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/README.md CHANGED
@@ -7,7 +7,6 @@ An extension of the `vaadin-grid` component that provides inline editing with fu
7
7
  [Documentation + Live Demo ↗](https://vaadin.com/docs/latest/components/grid-pro)
8
8
 
9
9
  [![npm version](https://badgen.net/npm/v/@vaadin/grid-pro)](https://www.npmjs.com/package/@vaadin/grid-pro)
10
- [![Discord](https://img.shields.io/discord/732335336448852018?label=discord)](https://discord.gg/PHmkCKC)
11
10
 
12
11
  ```html
13
12
  <vaadin-grid-pro>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/grid-pro",
3
- "version": "24.4.0-alpha9",
3
+ "version": "24.4.0-beta2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -39,15 +39,15 @@
39
39
  "dependencies": {
40
40
  "@open-wc/dedupe-mixin": "^1.3.0",
41
41
  "@polymer/polymer": "^3.0.0",
42
- "@vaadin/checkbox": "24.4.0-alpha9",
43
- "@vaadin/component-base": "24.4.0-alpha9",
44
- "@vaadin/grid": "24.4.0-alpha9",
45
- "@vaadin/lit-renderer": "24.4.0-alpha9",
46
- "@vaadin/select": "24.4.0-alpha9",
47
- "@vaadin/text-field": "24.4.0-alpha9",
48
- "@vaadin/vaadin-lumo-styles": "24.4.0-alpha9",
49
- "@vaadin/vaadin-material-styles": "24.4.0-alpha9",
50
- "@vaadin/vaadin-themable-mixin": "24.4.0-alpha9",
42
+ "@vaadin/checkbox": "24.4.0-beta2",
43
+ "@vaadin/component-base": "24.4.0-beta2",
44
+ "@vaadin/grid": "24.4.0-beta2",
45
+ "@vaadin/lit-renderer": "24.4.0-beta2",
46
+ "@vaadin/select": "24.4.0-beta2",
47
+ "@vaadin/text-field": "24.4.0-beta2",
48
+ "@vaadin/vaadin-lumo-styles": "24.4.0-beta2",
49
+ "@vaadin/vaadin-material-styles": "24.4.0-beta2",
50
+ "@vaadin/vaadin-themable-mixin": "24.4.0-beta2",
51
51
  "lit": "^3.0.0"
52
52
  },
53
53
  "devDependencies": {
@@ -60,5 +60,5 @@
60
60
  "web-types.json",
61
61
  "web-types.lit.json"
62
62
  ],
63
- "gitHead": "effb81abe3c6283a6ec620cc0cee56069af58226"
63
+ "gitHead": "886ab2e7ccb8353ac3b7a42ebb96dfe2d1211556"
64
64
  }
@@ -58,6 +58,24 @@ export declare class GridProEditColumnMixinClass<TItem> {
58
58
  */
59
59
  editorValuePath: string;
60
60
 
61
+ /**
62
+ * A function to check whether a specific cell of this column can be
63
+ * edited. This allows to disable editing of individual rows or cells,
64
+ * based on the item.
65
+ *
66
+ * Receives a `model` object containing the item for an individual row,
67
+ * and should return a boolean indicating whether the column's cell in
68
+ * that row is editable.
69
+ *
70
+ * The `model` object contains:
71
+ * - `model.index` The index of the item.
72
+ * - `model.item` The item.
73
+ * - `model.expanded` Sublevel toggle state.
74
+ * - `model.level` Level of the tree represented with a horizontal offset of the toggle button.
75
+ * - `model.selected` Selected state.
76
+ */
77
+ isCellEditable: (model: GridItemModel<TItem>) => boolean;
78
+
61
79
  protected _getEditorComponent(cell: HTMLElement): HTMLElement | null;
62
80
 
63
81
  protected _getEditorValue(editor: HTMLElement): unknown | null;
@@ -8,7 +8,6 @@
8
8
  * See https://vaadin.com/commercial-license-and-service-terms for the full
9
9
  * license.
10
10
  */
11
- import { addValueToAttribute } from '@vaadin/component-base/src/dom-utils.js';
12
11
  import { get, set } from '@vaadin/component-base/src/path-utils.js';
13
12
 
14
13
  /**
@@ -84,13 +83,36 @@ export const GridProEditColumnMixin = (superClass) =>
84
83
  sync: true,
85
84
  },
86
85
 
86
+ /**
87
+ * A function to check whether a specific cell of this column can be
88
+ * edited. This allows to disable editing of individual rows or cells,
89
+ * based on the item.
90
+ *
91
+ * Receives a `model` object containing the item for an individual row,
92
+ * and should return a boolean indicating whether the column's cell in
93
+ * that row is editable.
94
+ *
95
+ * The `model` object contains:
96
+ * - `model.index` The index of the item.
97
+ * - `model.item` The item.
98
+ * - `model.expanded` Sublevel toggle state.
99
+ * - `model.level` Level of the tree represented with a horizontal offset of the toggle button.
100
+ * - `model.selected` Selected state.
101
+ *
102
+ * @type {(model: GridItemModel) => boolean}
103
+ */
104
+ isCellEditable: {
105
+ type: Function,
106
+ observer: '_isCellEditableChanged',
107
+ },
108
+
87
109
  /** @private */
88
110
  _oldRenderer: Function,
89
111
  };
90
112
  }
91
113
 
92
114
  static get observers() {
93
- return ['_editModeRendererChanged(editModeRenderer, __initialized)', '_cellsChanged(_cells)'];
115
+ return ['_editModeRendererChanged(editModeRenderer, __initialized)'];
94
116
  }
95
117
 
96
118
  constructor() {
@@ -121,11 +143,9 @@ export const GridProEditColumnMixin = (superClass) =>
121
143
  }
122
144
 
123
145
  /** @private */
124
- _cellsChanged() {
125
- this._cells.forEach((cell) => {
126
- const target = cell._focusButton || cell;
127
- addValueToAttribute(target, 'part', 'editable-cell');
128
- });
146
+ _isCellEditableChanged(newValue, oldValue) {
147
+ // Re-render grid to update editable-cell part names
148
+ this._grid.requestContentUpdate();
129
149
  }
130
150
 
131
151
  /** @private */
@@ -267,8 +287,11 @@ export const GridProEditColumnMixin = (superClass) =>
267
287
  this._setEditorValue(editor, get(this.path, model.item));
268
288
  editor._grid = this._grid;
269
289
 
270
- this._focusEditor(editor);
271
- requestAnimationFrame(() => this._focusEditor(editor));
290
+ if (editor.updateComplete) {
291
+ editor.updateComplete.then(() => this._focusEditor(editor));
292
+ } else {
293
+ this._focusEditor(editor);
294
+ }
272
295
  }
273
296
 
274
297
  /**
@@ -11,6 +11,7 @@
11
11
  import { animationFrame } from '@vaadin/component-base/src/async.js';
12
12
  import { Debouncer } from '@vaadin/component-base/src/debounce.js';
13
13
  import { get, set } from '@vaadin/component-base/src/path-utils.js';
14
+ import { iterateRowCells, updatePart } from '@vaadin/grid/src/vaadin-grid-helpers.js';
14
15
 
15
16
  /**
16
17
  * @polymerMixin
@@ -218,6 +219,10 @@ export const InlineEditingMixin = (superClass) =>
218
219
  return;
219
220
  }
220
221
 
222
+ if (!this._isCellEditable(cell)) {
223
+ return;
224
+ }
225
+
221
226
  callback(e);
222
227
  }
223
228
  });
@@ -325,8 +330,10 @@ export const InlineEditingMixin = (superClass) =>
325
330
 
326
331
  /** @private */
327
332
  _startEdit(cell, column) {
333
+ const isCellEditable = this._isCellEditable(cell);
334
+
328
335
  // TODO: remove `_editingDisabled` after Flow counterpart is updated.
329
- if (this.disabled || this._editingDisabled) {
336
+ if (this.disabled || this._editingDisabled || !isCellEditable) {
330
337
  return;
331
338
  }
332
339
  // Cancel debouncer enqueued on focusout
@@ -421,59 +428,67 @@ export const InlineEditingMixin = (superClass) =>
421
428
 
422
429
  this._cancelStopEdit();
423
430
 
424
- const cols = this._getEditColumns();
425
-
431
+ const editableColumns = this._getEditColumns();
426
432
  const { cell, column, model } = this.__edited;
427
- const colIndex = cols.indexOf(column);
428
- const { index } = model;
429
433
 
430
- let nextCol = null;
431
- let nextIdx = index;
432
-
433
- // Enter key
434
- if (e.keyCode === 13) {
435
- nextCol = column;
436
-
437
- // Move up / down
438
- if (this.enterNextRow) {
439
- nextIdx = e.shiftKey ? index - 1 : index + 1;
440
- }
434
+ this._stopEdit();
435
+ e.preventDefault();
436
+ // Prevent vaadin-grid handler from being called
437
+ e.stopImmediatePropagation();
438
+
439
+ // Try to find the next editable cell
440
+ let nextIndex = model.index;
441
+ let nextColumn = column;
442
+ let nextCell = cell;
443
+ let directionX = 0;
444
+ let directionY = 0;
445
+
446
+ // Enter key: move up / down
447
+ if (e.keyCode === 13 && this.enterNextRow) {
448
+ directionY = e.shiftKey ? -1 : 1;
441
449
  }
442
450
 
443
451
  // Tab: move right / left
444
452
  if (e.keyCode === 9) {
445
- if (e.shiftKey) {
446
- if (cols[colIndex - 1]) {
447
- nextCol = cols[colIndex - 1];
448
- } else if (index > 0) {
449
- nextIdx = index - 1;
450
- nextCol = cols[cols.length - 1];
453
+ directionX = e.shiftKey ? -1 : 1;
454
+ }
455
+
456
+ if (directionX || directionY) {
457
+ while (nextCell) {
458
+ if (directionX) {
459
+ // Move horizontally
460
+ nextColumn = editableColumns[editableColumns.indexOf(nextColumn) + directionX];
461
+ if (!nextColumn) {
462
+ // Wrap to the next or previous row
463
+ nextIndex += directionX;
464
+ nextColumn = editableColumns[directionX > 0 ? 0 : editableColumns.length - 1];
465
+ }
466
+ }
467
+ // Move vertically
468
+ if (directionY) {
469
+ nextIndex += directionY;
470
+ }
471
+ // Stop looking if the next cell is editable
472
+ const nextRow = this._getRowByIndex(nextIndex);
473
+ // eslint-disable-next-line @typescript-eslint/no-loop-func
474
+ nextCell = nextRow && Array.from(nextRow.children).find((cell) => cell._column === nextColumn);
475
+ if (nextCell && this._isCellEditable(nextCell)) {
476
+ break;
451
477
  }
452
- } else if (cols[colIndex + 1]) {
453
- nextCol = cols[colIndex + 1];
454
- } else {
455
- nextIdx = index + 1;
456
- nextCol = cols[0];
457
478
  }
458
479
  }
459
480
 
460
- const nextRow = nextIdx === index ? cell.parentNode : this._getRowByIndex(nextIdx) || null;
461
-
462
- this._stopEdit();
463
-
464
- if (nextRow && nextCol) {
465
- const nextCell = Array.from(nextRow.children).find((cell) => cell._column === nextCol);
466
- e.preventDefault();
467
-
468
- // Prevent vaadin-grid handler from being called
469
- e.stopImmediatePropagation();
481
+ // Focus current cell as fallback
482
+ if (!nextCell) {
483
+ nextCell = cell;
484
+ nextIndex = model.index;
485
+ }
470
486
 
471
- if (!this.singleCellEdit && nextCell !== cell) {
472
- this._startEdit(nextCell, nextCol);
473
- } else {
474
- this._ensureScrolledToIndex(nextIdx);
475
- nextCell.focus();
476
- }
487
+ if (!this.singleCellEdit && nextCell !== cell) {
488
+ this._startEdit(nextCell, nextColumn);
489
+ } else {
490
+ this._ensureScrolledToIndex(nextIndex);
491
+ nextCell.focus();
477
492
  }
478
493
  }
479
494
 
@@ -492,6 +507,46 @@ export const InlineEditingMixin = (superClass) =>
492
507
  super._updateItem(row, item);
493
508
  }
494
509
 
510
+ /**
511
+ * Override method from `StylingMixin` to apply `editable-cell` part to the
512
+ * cells of edit columns.
513
+ *
514
+ * @override
515
+ */
516
+ _generateCellPartNames(row, model) {
517
+ super._generateCellPartNames(row, model);
518
+
519
+ iterateRowCells(row, (cell) => {
520
+ const isEditable = this._isCellEditable(cell);
521
+ const target = cell._focusButton || cell;
522
+ updatePart(target, isEditable, 'editable-cell');
523
+ });
524
+ }
525
+
526
+ /** @private */
527
+ _isCellEditable(cell) {
528
+ const column = cell._column;
529
+ // Not editable if the column is not an edit column
530
+ if (!this._isEditColumn(column)) {
531
+ return false;
532
+ }
533
+ // Cell is editable by default if isCellEditable is not configured
534
+ if (!column.isCellEditable) {
535
+ return true;
536
+ }
537
+ // Otherwise, check isCellEditable function
538
+ const model = this.__getRowModel(cell.parentElement);
539
+ const isEditable = column.isCellEditable(model);
540
+
541
+ // Cancel editing if the cell is currently edited one and becomes no longer editable
542
+ // TODO: should be moved to `_updateItem` when Grid connector is updated to use it.
543
+ if (this.__edited && this.__edited.cell === cell && !isEditable) {
544
+ this._stopEdit(true, true);
545
+ }
546
+
547
+ return isEditable;
548
+ }
549
+
495
550
  /**
496
551
  * Fired before exiting the cell edit mode, if the value has been changed.
497
552
  * If the default is prevented, value change would not be applied.
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/grid-pro",
4
- "version": "24.4.0-alpha9",
4
+ "version": "24.4.0-beta2",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -378,6 +378,17 @@
378
378
  "string"
379
379
  ]
380
380
  }
381
+ },
382
+ {
383
+ "name": "isCellEditable",
384
+ "description": "A function to check whether a specific cell of this column can be\nedited. This allows to disable editing of individual rows or cells,\nbased on the item.\n\nReceives a `model` object containing the item for an individual row,\nand should return a boolean indicating whether the column's cell in\nthat row is editable.\n\nThe `model` object contains:\n- `model.index` The index of the item.\n- `model.item` The item.\n- `model.expanded` Sublevel toggle state.\n- `model.level` Level of the tree represented with a horizontal offset of the toggle button.\n- `model.selected` Selected state.",
385
+ "value": {
386
+ "type": [
387
+ "Function",
388
+ "null",
389
+ "undefined"
390
+ ]
391
+ }
381
392
  }
382
393
  ],
383
394
  "events": [
@@ -390,7 +401,7 @@
390
401
  },
391
402
  {
392
403
  "name": "vaadin-grid-pro",
393
- "description": "`<vaadin-grid-pro>` is a high quality data grid / data table Web Component with extended functionality.\nIt extends `<vaadin-grid>` and adds extra features on top of the basic ones.\n\nSee [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-alpha9/#/elements/vaadin-grid) documentation for details.\n\n```\n<vaadin-grid-pro></vaadin-grid-pro>\n```\n\n### Internal components\n\nIn addition to `<vaadin-grid-pro>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-grid-pro-edit-checkbox>` - has the same API as [`<vaadin-checkbox>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-alpha9/#/elements/vaadin-checkbox).\n- `<vaadin-grid-pro-edit-text-field>` - has the same API as [`<vaadin-text-field>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-alpha9/#/elements/vaadin-text-field).\n- `<vaadin-grid-pro-edit-select>` - has the same API as [`<vaadin-select>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-alpha9/#/elements/vaadin-select).",
404
+ "description": "`<vaadin-grid-pro>` is a high quality data grid / data table Web Component with extended functionality.\nIt extends `<vaadin-grid>` and adds extra features on top of the basic ones.\n\nSee [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-beta2/#/elements/vaadin-grid) documentation for details.\n\n```\n<vaadin-grid-pro></vaadin-grid-pro>\n```\n\n### Internal components\n\nIn addition to `<vaadin-grid-pro>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-grid-pro-edit-checkbox>` - has the same API as [`<vaadin-checkbox>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-beta2/#/elements/vaadin-checkbox).\n- `<vaadin-grid-pro-edit-text-field>` - has the same API as [`<vaadin-text-field>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-beta2/#/elements/vaadin-text-field).\n- `<vaadin-grid-pro-edit-select>` - has the same API as [`<vaadin-select>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-beta2/#/elements/vaadin-select).",
394
405
  "attributes": [
395
406
  {
396
407
  "name": "size",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/grid-pro",
4
- "version": "24.4.0-alpha9",
4
+ "version": "24.4.0-beta2",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -159,6 +159,13 @@
159
159
  "kind": "expression"
160
160
  }
161
161
  },
162
+ {
163
+ "name": ".isCellEditable",
164
+ "description": "A function to check whether a specific cell of this column can be\nedited. This allows to disable editing of individual rows or cells,\nbased on the item.\n\nReceives a `model` object containing the item for an individual row,\nand should return a boolean indicating whether the column's cell in\nthat row is editable.\n\nThe `model` object contains:\n- `model.index` The index of the item.\n- `model.item` The item.\n- `model.expanded` Sublevel toggle state.\n- `model.level` Level of the tree represented with a horizontal offset of the toggle button.\n- `model.selected` Selected state.",
165
+ "value": {
166
+ "kind": "expression"
167
+ }
168
+ },
162
169
  {
163
170
  "name": "@editor-type-changed",
164
171
  "description": "Fired when the `editorType` property changes.",
@@ -170,7 +177,7 @@
170
177
  },
171
178
  {
172
179
  "name": "vaadin-grid-pro",
173
- "description": "`<vaadin-grid-pro>` is a high quality data grid / data table Web Component with extended functionality.\nIt extends `<vaadin-grid>` and adds extra features on top of the basic ones.\n\nSee [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-alpha9/#/elements/vaadin-grid) documentation for details.\n\n```\n<vaadin-grid-pro></vaadin-grid-pro>\n```\n\n### Internal components\n\nIn addition to `<vaadin-grid-pro>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-grid-pro-edit-checkbox>` - has the same API as [`<vaadin-checkbox>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-alpha9/#/elements/vaadin-checkbox).\n- `<vaadin-grid-pro-edit-text-field>` - has the same API as [`<vaadin-text-field>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-alpha9/#/elements/vaadin-text-field).\n- `<vaadin-grid-pro-edit-select>` - has the same API as [`<vaadin-select>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-alpha9/#/elements/vaadin-select).",
180
+ "description": "`<vaadin-grid-pro>` is a high quality data grid / data table Web Component with extended functionality.\nIt extends `<vaadin-grid>` and adds extra features on top of the basic ones.\n\nSee [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-beta2/#/elements/vaadin-grid) documentation for details.\n\n```\n<vaadin-grid-pro></vaadin-grid-pro>\n```\n\n### Internal components\n\nIn addition to `<vaadin-grid-pro>` itself, the following internal\ncomponents are themable:\n\n- `<vaadin-grid-pro-edit-checkbox>` - has the same API as [`<vaadin-checkbox>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-beta2/#/elements/vaadin-checkbox).\n- `<vaadin-grid-pro-edit-text-field>` - has the same API as [`<vaadin-text-field>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-beta2/#/elements/vaadin-text-field).\n- `<vaadin-grid-pro-edit-select>` - has the same API as [`<vaadin-select>`](https://cdn.vaadin.com/vaadin-web-components/24.4.0-beta2/#/elements/vaadin-select).",
174
181
  "extension": true,
175
182
  "attributes": [
176
183
  {