@vaadin/crud 24.0.0-alpha1 → 24.0.0-alpha3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/crud",
3
- "version": "24.0.0-alpha1",
3
+ "version": "24.0.0-alpha3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -37,16 +37,16 @@
37
37
  "dependencies": {
38
38
  "@open-wc/dedupe-mixin": "^1.3.0",
39
39
  "@polymer/polymer": "^3.0.0",
40
- "@vaadin/button": "24.0.0-alpha1",
41
- "@vaadin/component-base": "24.0.0-alpha1",
42
- "@vaadin/confirm-dialog": "24.0.0-alpha1",
43
- "@vaadin/dialog": "24.0.0-alpha1",
44
- "@vaadin/form-layout": "24.0.0-alpha1",
45
- "@vaadin/grid": "24.0.0-alpha1",
46
- "@vaadin/text-field": "24.0.0-alpha1",
47
- "@vaadin/vaadin-lumo-styles": "24.0.0-alpha1",
48
- "@vaadin/vaadin-material-styles": "24.0.0-alpha1",
49
- "@vaadin/vaadin-themable-mixin": "24.0.0-alpha1"
40
+ "@vaadin/button": "24.0.0-alpha3",
41
+ "@vaadin/component-base": "24.0.0-alpha3",
42
+ "@vaadin/confirm-dialog": "24.0.0-alpha3",
43
+ "@vaadin/dialog": "24.0.0-alpha3",
44
+ "@vaadin/form-layout": "24.0.0-alpha3",
45
+ "@vaadin/grid": "24.0.0-alpha3",
46
+ "@vaadin/text-field": "24.0.0-alpha3",
47
+ "@vaadin/vaadin-lumo-styles": "24.0.0-alpha3",
48
+ "@vaadin/vaadin-material-styles": "24.0.0-alpha3",
49
+ "@vaadin/vaadin-themable-mixin": "24.0.0-alpha3"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@esm-bundle/chai": "^4.3.4",
@@ -58,5 +58,5 @@
58
58
  "web-types.json",
59
59
  "web-types.lit.json"
60
60
  ],
61
- "gitHead": "427527c27c4b27822d61fd41d38d7b170134770b"
61
+ "gitHead": "7a013a3c5a56abd61dd4f7773c6ec77c3541bdf2"
62
62
  }
@@ -36,7 +36,7 @@ class CrudEditColumn extends GridColumn {
36
36
  */
37
37
  width: {
38
38
  type: String,
39
- value: '4em',
39
+ value: '4rem',
40
40
  },
41
41
 
42
42
  /**
@@ -68,13 +68,15 @@ class CrudGrid extends IncludedMixin(Grid) {
68
68
 
69
69
  /** @private */
70
70
  __toggleEditColumn() {
71
- const el = this.querySelector('vaadin-crud-edit-column');
71
+ let editColumn = this.querySelector('vaadin-crud-edit-column');
72
72
  if (this.hideEditColumn) {
73
- if (el) {
74
- this.removeChild(el);
73
+ if (editColumn) {
74
+ this.removeChild(editColumn);
75
75
  }
76
- } else if (!el) {
77
- this.appendChild(document.createElement('vaadin-crud-edit-column'));
76
+ } else if (!editColumn) {
77
+ editColumn = document.createElement('vaadin-crud-edit-column');
78
+ editColumn.frozenToEnd = true;
79
+ this.appendChild(editColumn);
78
80
  }
79
81
  }
80
82
 
@@ -194,7 +196,6 @@ class CrudGrid extends IncludedMixin(Grid) {
194
196
 
195
197
  const textField = window.document.createElement('vaadin-text-field');
196
198
  textField.setAttribute('theme', 'small');
197
- textField.setAttribute('slot', 'filter');
198
199
  textField.setAttribute('focus-target', true);
199
200
  textField.style.width = '100%';
200
201
  if (this.noSort) {
@@ -76,7 +76,7 @@ export type CrudNewEvent = CustomEvent<{ item: null }>;
76
76
  /**
77
77
  * Fired when user wants to edit an existing item.
78
78
  */
79
- export type CrudEditEvent<T> = CustomEvent<{ item: T }>;
79
+ export type CrudEditEvent<T> = CustomEvent<{ item: T; index: number }>;
80
80
 
81
81
  /**
82
82
  * Fired when user wants to delete item.
@@ -153,11 +153,15 @@ export type CrudEventMap<T> = CrudCustomEventMap<T> & HTMLElementEventMap;
153
153
  *
154
154
  * Alternatively you can fully configure the component by using `slot` names.
155
155
  *
156
- * Slot name | Description
157
- * ----------------|----------------
158
- * `grid` | To replace the auto-generated grid with a custom one.
159
- * `form` | To replace the auto-generated form.
160
- * `toolbar` | To replace the toolbar content. Add an element with the attribute `new-button` for the new item action.
156
+ * Slot name | Description
157
+ * ---------------|----------------
158
+ * `grid` | To replace the auto-generated grid with a custom one.
159
+ * `form` | To replace the auto-generated form.
160
+ * `save-button` | To replace the "Save" button.
161
+ * `cancel-button`| To replace the "Cancel" button.
162
+ * `delete-button`| To replace the "Delete" button.
163
+ * `toolbar` | To provide the toolbar content (by default, it's empty).
164
+ * `new-button` | To replace the "New item" button.
161
165
  *
162
166
  * #### Example:
163
167
  *
@@ -178,10 +182,12 @@ export type CrudEventMap<T> = CrudCustomEventMap<T> & HTMLElementEventMap;
178
182
  * <vaadin-text-field label="Surname" path="surname"></vaadin-text-field>
179
183
  * </vaadin-form-layout>
180
184
  *
181
- * <div slot="toolbar">
182
- * Total singers: [[size]]
183
- * <button new-button>New singer</button>
184
- * </div>
185
+ * <div slot="toolbar">Total singers: 2</div>
186
+ * <button slot="new-button">New singer</button>
187
+ *
188
+ * <button slot="save-button">Save changes</button>
189
+ * <button slot="cancel-button">Discard changes</button>
190
+ * <button slot="delete-button">Delete singer</button>
185
191
  * </vaadin-crud>
186
192
  * ```
187
193
  * ```js
@@ -15,9 +15,23 @@ import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
15
15
  import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
16
16
  import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
17
17
  import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js';
18
- import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
18
+ import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
19
19
  import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
20
20
 
21
+ /**
22
+ * @private
23
+ * A to initialize slotted button.
24
+ */
25
+ class ButtonSlotController extends SlotController {
26
+ constructor(host, type, theme) {
27
+ super(host, `${type}-button`, 'vaadin-button', {
28
+ initializer: (button) => {
29
+ button.setAttribute('theme', theme);
30
+ },
31
+ });
32
+ }
33
+ }
34
+
21
35
  /**
22
36
  * `<vaadin-crud>` is a Web Component for [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations.
23
37
  *
@@ -56,11 +70,15 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
56
70
  *
57
71
  * Alternatively you can fully configure the component by using `slot` names.
58
72
  *
59
- * Slot name | Description
60
- * ----------------|----------------
61
- * `grid` | To replace the auto-generated grid with a custom one.
62
- * `form` | To replace the auto-generated form.
63
- * `toolbar` | To replace the toolbar content. Add an element with the attribute `new-button` for the new item action.
73
+ * Slot name | Description
74
+ * ---------------|----------------
75
+ * `grid` | To replace the auto-generated grid with a custom one.
76
+ * `form` | To replace the auto-generated form.
77
+ * `save-button` | To replace the "Save" button.
78
+ * `cancel-button`| To replace the "Cancel" button.
79
+ * `delete-button`| To replace the "Delete" button.
80
+ * `toolbar` | To provide the toolbar content (by default, it's empty).
81
+ * `new-button` | To replace the "New item" button.
64
82
  *
65
83
  * #### Example:
66
84
  *
@@ -81,10 +99,12 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
81
99
  * <vaadin-text-field label="Surname" path="surname"></vaadin-text-field>
82
100
  * </vaadin-form-layout>
83
101
  *
84
- * <div slot="toolbar">
85
- * Total singers: [[size]]
86
- * <button new-button>New singer</button>
87
- * </div>
102
+ * <div slot="toolbar">Total singers: 2</div>
103
+ * <button slot="new-button">New singer</button>
104
+ *
105
+ * <button slot="save-button">Save changes</button>
106
+ * <button slot="cancel-button">Discard changes</button>
107
+ * <button slot="delete-button">Delete singer</button>
88
108
  * </vaadin-crud>
89
109
  * ```
90
110
  * ```js
@@ -144,10 +164,9 @@ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mix
144
164
  * @extends HTMLElement
145
165
  * @mixes ControllerMixin
146
166
  * @mixes ElementMixin
147
- * @mixes SlotMixin
148
167
  * @mixes ThemableMixin
149
168
  */
150
- class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerElement)))) {
169
+ class Crud extends ControllerMixin(ElementMixin(ThemableMixin(PolymerElement))) {
151
170
  static get template() {
152
171
  return html`
153
172
  <style>
@@ -233,23 +252,11 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
233
252
 
234
253
  <div id="container">
235
254
  <div id="main">
236
- <slot name="grid">
237
- <vaadin-crud-grid
238
- theme$="[[_theme]]"
239
- id="grid"
240
- include="[[include]]"
241
- exclude="[[exclude]]"
242
- no-sort="[[noSort]]"
243
- no-filter="[[noFilter]]"
244
- no-head="[[noHead]]"
245
- hide-edit-column="[[editOnClick]]"
246
- ></vaadin-crud-grid>
247
- </slot>
248
-
249
- <div id="toolbar" part="toolbar" on-click="__new">
250
- <slot name="toolbar">
251
- <vaadin-button new-button="" id="new" theme="primary">[[i18n.newItem]]</vaadin-button>
252
- </slot>
255
+ <slot name="grid"></slot>
256
+
257
+ <div id="toolbar" part="toolbar">
258
+ <slot name="toolbar"></slot>
259
+ <slot name="new-button"></slot>
253
260
  </div>
254
261
  </div>
255
262
 
@@ -320,7 +327,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
320
327
  * @private
321
328
  */
322
329
  _grid: {
323
- type: HTMLElement,
330
+ type: Object,
324
331
  observer: '__gridChanged',
325
332
  },
326
333
 
@@ -329,7 +336,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
329
336
  * @private
330
337
  */
331
338
  _form: {
332
- type: HTMLElement,
339
+ type: Object,
333
340
  observer: '__formChanged',
334
341
  },
335
342
 
@@ -338,34 +345,39 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
338
345
  * @private
339
346
  */
340
347
  _saveButton: {
341
- type: HTMLElement,
342
- observer: '__saveButtonChanged',
348
+ type: Object,
343
349
  },
344
350
 
345
351
  /**
346
- * A reference to the save button which will be teleported to the dialog
352
+ * A reference to the delete button which will be teleported to the dialog
347
353
  * @private
348
354
  */
349
355
  _deleteButton: {
350
- type: HTMLElement,
351
- observer: '__deleteButtonChanged',
356
+ type: Object,
352
357
  },
353
358
 
354
359
  /**
355
- * A reference to the save button which will be teleported to the dialog
360
+ * A reference to the cancel button which will be teleported to the dialog
356
361
  * @private
357
362
  */
358
363
  _cancelButton: {
359
- type: HTMLElement,
360
- observer: '__cancelButtonChanged',
364
+ type: Object,
365
+ },
366
+
367
+ /**
368
+ * A reference to the default editor header element created by the CRUD
369
+ * @private
370
+ */
371
+ _defaultHeader: {
372
+ type: Object,
361
373
  },
362
374
 
363
375
  /**
364
- * A reference to the editor header element will be teleported to the dialog.
376
+ * A reference to the "New item" button
365
377
  * @private
366
378
  */
367
- _headerNode: {
368
- type: HTMLElement,
379
+ _newButton: {
380
+ type: Object,
369
381
  },
370
382
 
371
383
  /**
@@ -604,13 +616,15 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
604
616
 
605
617
  static get observers() {
606
618
  return [
607
- '__headerPropsChanged(_headerNode, __isNew, i18n.newItem, i18n.editItem)',
619
+ '__headerPropsChanged(_defaultHeader, __isNew, i18n.newItem, i18n.editItem)',
608
620
  '__formPropsChanged(_form, _theme, include, exclude)',
621
+ '__gridPropsChanged(_grid, _theme, include, exclude, noFilter, noHead, noSort)',
609
622
  '__i18nChanged(i18n, _grid)',
610
623
  '__editOnClickChanged(editOnClick, _grid)',
611
624
  '__saveButtonPropsChanged(_saveButton, i18n.saveItem, __isDirty)',
612
625
  '__cancelButtonPropsChanged(_cancelButton, i18n.cancel)',
613
626
  '__deleteButtonPropsChanged(_deleteButton, i18n.deleteItem, __isNew)',
627
+ '__newButtonPropsChanged(_newButton, i18n.newItem)',
614
628
  ];
615
629
  }
616
630
 
@@ -620,39 +634,22 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
620
634
  }
621
635
 
622
636
  /** @protected */
623
- get slots() {
624
- // NOTE: order in which the toolbar buttons are listed matters.
625
- return {
626
- ...super.slots,
627
- header: () => {
628
- return document.createElement('h3');
629
- },
630
- form: () => {
631
- return document.createElement('vaadin-crud-form');
632
- },
633
- 'save-button': () => {
634
- const button = document.createElement('vaadin-button');
635
- button.id = 'save';
636
- button.setAttribute('theme', 'primary');
637
- return button;
638
- },
639
- 'cancel-button': () => {
640
- const button = document.createElement('vaadin-button');
641
- button.id = 'cancel';
642
- button.setAttribute('theme', 'tertiary');
643
- return button;
644
- },
645
- 'delete-button': () => {
646
- const button = document.createElement('vaadin-button');
647
- button.id = 'delete';
648
- button.setAttribute('theme', 'tertiary error');
649
- return button;
650
- },
651
- };
637
+ get _headerNode() {
638
+ return this._headerController && this._headerController.node;
652
639
  }
653
640
 
654
641
  constructor() {
655
642
  super();
643
+
644
+ this.__cancel = this.__cancel.bind(this);
645
+ this.__delete = this.__delete.bind(this);
646
+ this.__save = this.__save.bind(this);
647
+ this.__new = this.__new.bind(this);
648
+ this.__onFormChange = this.__onFormChange.bind(this);
649
+ this.__onGridEdit = this.__onGridEdit.bind(this);
650
+ this.__onGridSizeChanged = this.__onGridSizeChanged.bind(this);
651
+ this.__onGridActiveItemChanged = this.__onGridActiveItemChanged.bind(this);
652
+
656
653
  this._observer = new FlattenedNodesObserver(this, (info) => {
657
654
  this.__onDomChange(info.addedNodes);
658
655
  });
@@ -661,17 +658,29 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
661
658
  /** @protected */
662
659
  ready() {
663
660
  super.ready();
664
- this.__save = this.__save.bind(this);
665
- this.__cancel = this.__cancel.bind(this);
666
- this.__delete = this.__delete.bind(this);
667
- this.__onFormChange = this.__onFormChange.bind(this);
668
- this.__onGridEdit = this.__onGridEdit.bind(this);
669
- this.__onGridSizeChanged = this.__onGridSizeChanged.bind(this);
670
- this.__onGridActiveItemChanged = this.__onGridActiveItemChanged.bind(this);
671
- this._grid = this.$.grid;
661
+
672
662
  this.$.dialog.$.overlay.addEventListener('vaadin-overlay-outside-click', this.__cancel);
673
663
  this.$.dialog.$.overlay.addEventListener('vaadin-overlay-escape-press', this.__cancel);
674
664
 
665
+ this._headerController = new SlotController(this, 'header', 'h3', {
666
+ initializer: (node) => {
667
+ this._defaultHeader = node;
668
+ },
669
+ });
670
+ this.addController(this._headerController);
671
+
672
+ this._gridController = new SlotController(this, 'grid', 'vaadin-crud-grid');
673
+ this.addController(this._gridController);
674
+
675
+ this.addController(new SlotController(this, 'form', 'vaadin-crud-form'));
676
+
677
+ this.addController(new ButtonSlotController(this, 'new', 'primary'));
678
+
679
+ // NOTE: order in which buttons are added should match the order of slots in template
680
+ this.addController(new ButtonSlotController(this, 'save', 'primary'));
681
+ this.addController(new ButtonSlotController(this, 'cancel', 'tertiary'));
682
+ this.addController(new ButtonSlotController(this, 'delete', 'tertiary error'));
683
+
675
684
  this.addController(
676
685
  new MediaQueryController(this._fullscreenMediaQuery, (matches) => {
677
686
  this._fullscreen = matches;
@@ -824,7 +833,8 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
824
833
  /** @private */
825
834
  __onDomChange(addedNodes) {
826
835
  // TODO: restore default button when a corresponding slotted button is removed.
827
- // Consider creating a controller to reuse custom helper logic from FieldMixin.
836
+ // This would require us to detect where to insert a button after teleporting it,
837
+ // which happens after opening a dialog and closing it (default editor position).
828
838
  addedNodes
829
839
  .filter((node) => node.nodeType === Node.ELEMENT_NODE)
830
840
  .forEach((node) => {
@@ -842,9 +852,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
842
852
  this._form = node;
843
853
  } else if (slotAttributeValue.indexOf('button') >= 0) {
844
854
  const [button] = slotAttributeValue.split('-');
845
- this[`_${button}Button`] = node;
846
- } else if (slotAttributeValue === 'header') {
847
- this._headerNode = node;
855
+ this.__setupSlottedButton(button, node);
848
856
  }
849
857
  });
850
858
 
@@ -928,17 +936,39 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
928
936
  if (form) {
929
937
  form.include = include;
930
938
  form.exclude = exclude;
931
- form.setAttribute('theme', theme);
939
+
940
+ if (theme) {
941
+ form.setAttribute('theme', theme);
942
+ } else {
943
+ form.removeAttribute('theme');
944
+ }
932
945
  }
933
946
  }
934
947
 
935
948
  /**
936
- * @param {HTMLElement} saveButton
937
- * @param {HTMLElement | undefined} oldSaveButton
949
+ * @param {HTMLElement | undefined} form
950
+ * @param {string} theme
951
+ * @param {string | string[] | undefined} include
952
+ * @param {string | RegExp} exclude
938
953
  * @private
939
954
  */
940
- __saveButtonChanged(saveButton, oldSaveButton) {
941
- this.__setupSlottedButton(saveButton, oldSaveButton, this.__save);
955
+ // eslint-disable-next-line max-params
956
+ __gridPropsChanged(grid, theme, include, exclude, noFilter, noHead, noSort) {
957
+ if (grid) {
958
+ if (grid === this._gridController.defaultNode) {
959
+ grid.include = include;
960
+ grid.exclude = exclude;
961
+ grid.noFilter = noFilter;
962
+ grid.noHead = noHead;
963
+ grid.noSort = noSort;
964
+ }
965
+
966
+ if (theme) {
967
+ grid.setAttribute('theme', theme);
968
+ } else {
969
+ grid.removeAttribute('theme');
970
+ }
971
+ }
942
972
  }
943
973
 
944
974
  /**
@@ -954,15 +984,6 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
954
984
  }
955
985
  }
956
986
 
957
- /**
958
- * @param {HTMLElement} deleteButton
959
- * @param {HTMLElement | undefined} oldDeleteButton
960
- * @private
961
- */
962
- __deleteButtonChanged(deleteButton, oldDeleteButton) {
963
- this.__setupSlottedButton(deleteButton, oldDeleteButton, this.__delete);
964
- }
965
-
966
987
  /**
967
988
  * @param {HTMLElement | undefined} deleteButton
968
989
  * @param {string} i18nLabel
@@ -976,15 +997,6 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
976
997
  }
977
998
  }
978
999
 
979
- /**
980
- * @param {HTMLElement} cancelButton
981
- * @param {HTMLElement | undefined} oldCancelButton
982
- * @private
983
- */
984
- __cancelButtonChanged(cancelButton, oldCancelButton) {
985
- this.__setupSlottedButton(cancelButton, oldCancelButton, this.__cancel);
986
- }
987
-
988
1000
  /**
989
1001
  * @param {HTMLElement | undefined} saveButton
990
1002
  * @param {string} i18nLabel
@@ -997,17 +1009,31 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
997
1009
  }
998
1010
 
999
1011
  /**
1012
+ * @param {HTMLElement | undefined} newButton
1013
+ * @param {string} i18nNewItem
1014
+ * @private
1015
+ */
1016
+ __newButtonPropsChanged(newButton, i18nNewItem) {
1017
+ if (newButton) {
1018
+ newButton.textContent = i18nNewItem;
1019
+ }
1020
+ }
1021
+
1022
+ /**
1023
+ * @param {string} type
1000
1024
  * @param {HTMLElement} newButton
1001
- * @param {HTMLElement | undefined | null} oldButton
1002
- * @param {Function} clickListener
1003
1025
  * @private
1004
1026
  */
1005
- __setupSlottedButton(newButton, oldButton, clickListener) {
1006
- if (oldButton && oldButton.parentElement) {
1007
- oldButton.parentElement.removeChild(oldButton);
1027
+ __setupSlottedButton(type, button) {
1028
+ const property = `_${type}Button`;
1029
+ const listener = `__${type}`;
1030
+
1031
+ if (this[property] && this[property] !== button) {
1032
+ this[property].remove();
1008
1033
  }
1009
1034
 
1010
- newButton.addEventListener('click', clickListener);
1035
+ button.addEventListener('click', this[listener]);
1036
+ this[property] = button;
1011
1037
  }
1012
1038
 
1013
1039
  /** @private */
@@ -1018,15 +1044,17 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
1018
1044
  }
1019
1045
 
1020
1046
  /** @private */
1021
- __editOnClickChanged(editOnClick, _grid) {
1022
- if (!_grid) {
1047
+ __editOnClickChanged(editOnClick, grid) {
1048
+ if (!grid) {
1023
1049
  return;
1024
1050
  }
1025
1051
 
1052
+ grid.hideEditColumn = editOnClick;
1053
+
1026
1054
  if (editOnClick) {
1027
- _grid.addEventListener('active-item-changed', this.__onGridActiveItemChanged);
1055
+ grid.addEventListener('active-item-changed', this.__onGridActiveItemChanged);
1028
1056
  } else {
1029
- _grid.removeEventListener('active-item-changed', this.__onGridActiveItemChanged);
1057
+ grid.removeEventListener('active-item-changed', this.__onGridActiveItemChanged);
1030
1058
  }
1031
1059
  }
1032
1060
 
@@ -1155,7 +1183,7 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
1155
1183
 
1156
1184
  /** @private */
1157
1185
  __setHighlightedItem(item) {
1158
- if (this._grid === this.$.grid) {
1186
+ if (this._grid === this._gridController.defaultNode) {
1159
1187
  this._grid.selectedItems = item ? [item] : [];
1160
1188
  }
1161
1189
  }
@@ -1171,11 +1199,8 @@ class Crud extends SlotMixin(ControllerMixin(ElementMixin(ThemableMixin(PolymerE
1171
1199
  }
1172
1200
 
1173
1201
  /** @private */
1174
- __new(event) {
1175
- // This allows listening to parent element and fire only when clicking on default or custom new-button.
1176
- if (event.composedPath().some((e) => e.nodeType === 1 && e.hasAttribute('new-button'))) {
1177
- this.__confirmBeforeChangingEditedItem(null, true);
1178
- }
1202
+ __new() {
1203
+ this.__confirmBeforeChangingEditedItem(null, true);
1179
1204
  }
1180
1205
 
1181
1206
  /** @private */
@@ -97,13 +97,6 @@ registerStyles(
97
97
  :host([dir='rtl']) [part='toolbar'] ::slotted(*:not(:first-child)) {
98
98
  margin-right: 0.5em;
99
99
  }
100
-
101
- vaadin-text-field[theme~='small'] {
102
- height: 24px;
103
- font-size: var(--material-small-font-size);
104
- margin: 0;
105
- padding: 0;
106
- }
107
100
  `,
108
101
  ],
109
102
  { moduleId: 'material-crud' },
@@ -0,0 +1 @@
1
+ export * from './src/vaadin-crud-edit-column.js';
@@ -0,0 +1 @@
1
+ export * from './src/vaadin-crud-edit-column.js';
@@ -0,0 +1 @@
1
+ export * from './src/vaadin-crud-edit.js';
@@ -0,0 +1 @@
1
+ export * from './src/vaadin-crud-edit.js';
package/web-types.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/crud",
4
- "version": "24.0.0-alpha1",
4
+ "version": "24.0.0-alpha3",
5
5
  "description-markup": "markdown",
6
6
  "contributions": {
7
7
  "html": {
@@ -295,7 +295,7 @@
295
295
  },
296
296
  {
297
297
  "name": "vaadin-crud",
298
- "description": "`<vaadin-crud>` is a Web Component for [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations.\n\n### Quick Start\n\nAssign an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-items) property.\n\nA grid and an editor will be automatically generated and configured based on the data structure provided.\n\n#### Example:\n```html\n<vaadin-crud items='[{\"name\": \"John\", \"surname\": \"Lennon\", \"role\": \"singer\"},\n {\"name\": \"Ringo\", \"surname\": \"Starr\", \"role\": \"drums\"}]'></vaadin-crud>\n```\n\n### Data Provider Function\n\nOtherwise, you can provide a [`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-dataProvider) function.\n#### Example:\n```html\n<vaadin-crud></vaadin-crud>\n```\n```js\nconst crud = document.querySelector('vaadin-crud');\nconst users = [{'name': 'John', 'surname': 'Lennon', 'role': 'singer'}, ...];\ncrud.dataProvider = function(params, callback) {\n const chunk = users.slice(params.page * params.pageSize, params.page * params.pageSize + params.pageSize);\n callback(chunk, people.length);\n};\n```\n\nNOTE: The auto-generated editor only supports string types. If you need to handle special cases\ncustomizing the editor is discussed below.\n\n### Customization\n\nAlternatively you can fully configure the component by using `slot` names.\n\nSlot name | Description\n----------------|----------------\n`grid` | To replace the auto-generated grid with a custom one.\n`form` | To replace the auto-generated form.\n`toolbar` | To replace the toolbar content. Add an element with the attribute `new-button` for the new item action.\n\n#### Example:\n\n```html\n<vaadin-crud\n id=\"crud\"\n items='[{\"name\": \"John\", \"surname\": \"Lennon\", \"role\": \"singer\"},\n {\"name\": \"Ringo\", \"surname\": \"Starr\", \"role\": \"drums\"}]'\n>\n <vaadin-grid slot=\"grid\">\n <vaadin-crud-edit-column></vaadin-crud-edit-column>\n <vaadin-grid-column id=\"column1\"></vaadin-grid-column>\n <vaadin-grid-column id=\"column2\"></vaadin-grid-column>\n </vaadin-grid>\n\n <vaadin-form-layout slot=\"form\">\n <vaadin-text-field label=\"First\" path=\"name\"></vaadin-text-field>\n <vaadin-text-field label=\"Surname\" path=\"surname\"></vaadin-text-field>\n </vaadin-form-layout>\n\n <div slot=\"toolbar\">\n Total singers: [[size]]\n <button new-button>New singer</button>\n </div>\n</vaadin-crud>\n```\n```js\nconst crud = document.querySelector('#crud');\n\nconst column1 = document.querySelector('#column1');\ncolumn1.headerRenderer = (root, column) => {\n root.textContent = 'Name';\n};\ncolumn1.renderer = (root, column, model) => {\n root.textContent = model.item.name;\n};\n\nconst column2 = document.querySelector('#column2');\ncolumn2.headerRenderer = (root, column) => {\n root.textContent = 'Surname';\n};\ncolumn2.renderer = (root, column, model) => {\n root.textContent = model.item.surname;\n};\n```\n\n### Helpers\n\nThe following elements are used to auto-configure the grid and the editor\n- [`<vaadin-crud-edit-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud-edit-column)\n- `<vaadin-crud-grid>` - can be replaced with custom [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-grid)\n- `<vaadin-crud-form>` - can be replaced with custom [`<vaadin-form-layout>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-form-layout)\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n----------------|----------------\n`toolbar` | Toolbar container at the bottom. By default it contains the the `new` button\n\nThe following custom properties are available:\n\nCustom Property | Description | Default\n----------------|----------------\n--vaadin-crud-editor-max-height | max height of editor when opened on the bottom | 40%\n--vaadin-crud-editor-max-width | max width of editor when opened on the side | 40%\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
298
+ "description": "`<vaadin-crud>` is a Web Component for [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations.\n\n### Quick Start\n\nAssign an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-items) property.\n\nA grid and an editor will be automatically generated and configured based on the data structure provided.\n\n#### Example:\n```html\n<vaadin-crud items='[{\"name\": \"John\", \"surname\": \"Lennon\", \"role\": \"singer\"},\n {\"name\": \"Ringo\", \"surname\": \"Starr\", \"role\": \"drums\"}]'></vaadin-crud>\n```\n\n### Data Provider Function\n\nOtherwise, you can provide a [`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-dataProvider) function.\n#### Example:\n```html\n<vaadin-crud></vaadin-crud>\n```\n```js\nconst crud = document.querySelector('vaadin-crud');\nconst users = [{'name': 'John', 'surname': 'Lennon', 'role': 'singer'}, ...];\ncrud.dataProvider = function(params, callback) {\n const chunk = users.slice(params.page * params.pageSize, params.page * params.pageSize + params.pageSize);\n callback(chunk, people.length);\n};\n```\n\nNOTE: The auto-generated editor only supports string types. If you need to handle special cases\ncustomizing the editor is discussed below.\n\n### Customization\n\nAlternatively you can fully configure the component by using `slot` names.\n\nSlot name | Description\n---------------|----------------\n`grid` | To replace the auto-generated grid with a custom one.\n`form` | To replace the auto-generated form.\n`save-button` | To replace the \"Save\" button.\n`cancel-button`| To replace the \"Cancel\" button.\n`delete-button`| To replace the \"Delete\" button.\n`toolbar` | To provide the toolbar content (by default, it's empty).\n`new-button` | To replace the \"New item\" button.\n\n#### Example:\n\n```html\n<vaadin-crud\n id=\"crud\"\n items='[{\"name\": \"John\", \"surname\": \"Lennon\", \"role\": \"singer\"},\n {\"name\": \"Ringo\", \"surname\": \"Starr\", \"role\": \"drums\"}]'\n>\n <vaadin-grid slot=\"grid\">\n <vaadin-crud-edit-column></vaadin-crud-edit-column>\n <vaadin-grid-column id=\"column1\"></vaadin-grid-column>\n <vaadin-grid-column id=\"column2\"></vaadin-grid-column>\n </vaadin-grid>\n\n <vaadin-form-layout slot=\"form\">\n <vaadin-text-field label=\"First\" path=\"name\"></vaadin-text-field>\n <vaadin-text-field label=\"Surname\" path=\"surname\"></vaadin-text-field>\n </vaadin-form-layout>\n\n <div slot=\"toolbar\">Total singers: 2</div>\n <button slot=\"new-button\">New singer</button>\n\n <button slot=\"save-button\">Save changes</button>\n <button slot=\"cancel-button\">Discard changes</button>\n <button slot=\"delete-button\">Delete singer</button>\n</vaadin-crud>\n```\n```js\nconst crud = document.querySelector('#crud');\n\nconst column1 = document.querySelector('#column1');\ncolumn1.headerRenderer = (root, column) => {\n root.textContent = 'Name';\n};\ncolumn1.renderer = (root, column, model) => {\n root.textContent = model.item.name;\n};\n\nconst column2 = document.querySelector('#column2');\ncolumn2.headerRenderer = (root, column) => {\n root.textContent = 'Surname';\n};\ncolumn2.renderer = (root, column, model) => {\n root.textContent = model.item.surname;\n};\n```\n\n### Helpers\n\nThe following elements are used to auto-configure the grid and the editor\n- [`<vaadin-crud-edit-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud-edit-column)\n- `<vaadin-crud-grid>` - can be replaced with custom [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-grid)\n- `<vaadin-crud-form>` - can be replaced with custom [`<vaadin-form-layout>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-form-layout)\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n----------------|----------------\n`toolbar` | Toolbar container at the bottom. By default it contains the the `new` button\n\nThe following custom properties are available:\n\nCustom Property | Description | Default\n----------------|----------------\n--vaadin-crud-editor-max-height | max height of editor when opened on the bottom | 40%\n--vaadin-crud-editor-max-width | max width of editor when opened on the side | 40%\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
299
299
  "attributes": [
300
300
  {
301
301
  "name": "editor-position",
@@ -350,7 +350,7 @@
350
350
  },
351
351
  {
352
352
  "name": "include",
353
- "description": "A comma-separated list of fields to include in the generated grid and the generated editor.\n\nIt can be used to explicitly define the field order.\n\nWhen it is defined [`exclude`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-exclude) is ignored.\n\nDefault is undefined meaning that all properties in the object should be mapped to fields.",
353
+ "description": "A comma-separated list of fields to include in the generated grid and the generated editor.\n\nIt can be used to explicitly define the field order.\n\nWhen it is defined [`exclude`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-exclude) is ignored.\n\nDefault is undefined meaning that all properties in the object should be mapped to fields.",
354
354
  "value": {
355
355
  "type": [
356
356
  "string",
@@ -361,7 +361,7 @@
361
361
  },
362
362
  {
363
363
  "name": "exclude",
364
- "description": "A comma-separated list of fields to be excluded from the generated grid and the generated editor.\n\nWhen [`include`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-include) is defined, this parameter is ignored.\n\nDefault is to exclude all private fields (those properties starting with underscore)",
364
+ "description": "A comma-separated list of fields to be excluded from the generated grid and the generated editor.\n\nWhen [`include`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-include) is defined, this parameter is ignored.\n\nDefault is to exclude all private fields (those properties starting with underscore)",
365
365
  "value": {
366
366
  "type": [
367
367
  "string",
@@ -488,7 +488,7 @@
488
488
  },
489
489
  {
490
490
  "name": "include",
491
- "description": "A comma-separated list of fields to include in the generated grid and the generated editor.\n\nIt can be used to explicitly define the field order.\n\nWhen it is defined [`exclude`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-exclude) is ignored.\n\nDefault is undefined meaning that all properties in the object should be mapped to fields.",
491
+ "description": "A comma-separated list of fields to include in the generated grid and the generated editor.\n\nIt can be used to explicitly define the field order.\n\nWhen it is defined [`exclude`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-exclude) is ignored.\n\nDefault is undefined meaning that all properties in the object should be mapped to fields.",
492
492
  "value": {
493
493
  "type": [
494
494
  "string",
@@ -499,7 +499,7 @@
499
499
  },
500
500
  {
501
501
  "name": "exclude",
502
- "description": "A comma-separated list of fields to be excluded from the generated grid and the generated editor.\n\nWhen [`include`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-include) is defined, this parameter is ignored.\n\nDefault is to exclude all private fields (those properties starting with underscore)",
502
+ "description": "A comma-separated list of fields to be excluded from the generated grid and the generated editor.\n\nWhen [`include`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-include) is defined, this parameter is ignored.\n\nDefault is to exclude all private fields (those properties starting with underscore)",
503
503
  "value": {
504
504
  "type": [
505
505
  "string",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/web-types",
3
3
  "name": "@vaadin/crud",
4
- "version": "24.0.0-alpha1",
4
+ "version": "24.0.0-alpha3",
5
5
  "description-markup": "markdown",
6
6
  "framework": "lit",
7
7
  "framework-config": {
@@ -121,7 +121,7 @@
121
121
  },
122
122
  {
123
123
  "name": "vaadin-crud",
124
- "description": "`<vaadin-crud>` is a Web Component for [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations.\n\n### Quick Start\n\nAssign an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-items) property.\n\nA grid and an editor will be automatically generated and configured based on the data structure provided.\n\n#### Example:\n```html\n<vaadin-crud items='[{\"name\": \"John\", \"surname\": \"Lennon\", \"role\": \"singer\"},\n {\"name\": \"Ringo\", \"surname\": \"Starr\", \"role\": \"drums\"}]'></vaadin-crud>\n```\n\n### Data Provider Function\n\nOtherwise, you can provide a [`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-dataProvider) function.\n#### Example:\n```html\n<vaadin-crud></vaadin-crud>\n```\n```js\nconst crud = document.querySelector('vaadin-crud');\nconst users = [{'name': 'John', 'surname': 'Lennon', 'role': 'singer'}, ...];\ncrud.dataProvider = function(params, callback) {\n const chunk = users.slice(params.page * params.pageSize, params.page * params.pageSize + params.pageSize);\n callback(chunk, people.length);\n};\n```\n\nNOTE: The auto-generated editor only supports string types. If you need to handle special cases\ncustomizing the editor is discussed below.\n\n### Customization\n\nAlternatively you can fully configure the component by using `slot` names.\n\nSlot name | Description\n----------------|----------------\n`grid` | To replace the auto-generated grid with a custom one.\n`form` | To replace the auto-generated form.\n`toolbar` | To replace the toolbar content. Add an element with the attribute `new-button` for the new item action.\n\n#### Example:\n\n```html\n<vaadin-crud\n id=\"crud\"\n items='[{\"name\": \"John\", \"surname\": \"Lennon\", \"role\": \"singer\"},\n {\"name\": \"Ringo\", \"surname\": \"Starr\", \"role\": \"drums\"}]'\n>\n <vaadin-grid slot=\"grid\">\n <vaadin-crud-edit-column></vaadin-crud-edit-column>\n <vaadin-grid-column id=\"column1\"></vaadin-grid-column>\n <vaadin-grid-column id=\"column2\"></vaadin-grid-column>\n </vaadin-grid>\n\n <vaadin-form-layout slot=\"form\">\n <vaadin-text-field label=\"First\" path=\"name\"></vaadin-text-field>\n <vaadin-text-field label=\"Surname\" path=\"surname\"></vaadin-text-field>\n </vaadin-form-layout>\n\n <div slot=\"toolbar\">\n Total singers: [[size]]\n <button new-button>New singer</button>\n </div>\n</vaadin-crud>\n```\n```js\nconst crud = document.querySelector('#crud');\n\nconst column1 = document.querySelector('#column1');\ncolumn1.headerRenderer = (root, column) => {\n root.textContent = 'Name';\n};\ncolumn1.renderer = (root, column, model) => {\n root.textContent = model.item.name;\n};\n\nconst column2 = document.querySelector('#column2');\ncolumn2.headerRenderer = (root, column) => {\n root.textContent = 'Surname';\n};\ncolumn2.renderer = (root, column, model) => {\n root.textContent = model.item.surname;\n};\n```\n\n### Helpers\n\nThe following elements are used to auto-configure the grid and the editor\n- [`<vaadin-crud-edit-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud-edit-column)\n- `<vaadin-crud-grid>` - can be replaced with custom [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-grid)\n- `<vaadin-crud-form>` - can be replaced with custom [`<vaadin-form-layout>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-form-layout)\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n----------------|----------------\n`toolbar` | Toolbar container at the bottom. By default it contains the the `new` button\n\nThe following custom properties are available:\n\nCustom Property | Description | Default\n----------------|----------------\n--vaadin-crud-editor-max-height | max height of editor when opened on the bottom | 40%\n--vaadin-crud-editor-max-width | max width of editor when opened on the side | 40%\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
124
+ "description": "`<vaadin-crud>` is a Web Component for [CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations.\n\n### Quick Start\n\nAssign an array to the [`items`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-items) property.\n\nA grid and an editor will be automatically generated and configured based on the data structure provided.\n\n#### Example:\n```html\n<vaadin-crud items='[{\"name\": \"John\", \"surname\": \"Lennon\", \"role\": \"singer\"},\n {\"name\": \"Ringo\", \"surname\": \"Starr\", \"role\": \"drums\"}]'></vaadin-crud>\n```\n\n### Data Provider Function\n\nOtherwise, you can provide a [`dataProvider`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-dataProvider) function.\n#### Example:\n```html\n<vaadin-crud></vaadin-crud>\n```\n```js\nconst crud = document.querySelector('vaadin-crud');\nconst users = [{'name': 'John', 'surname': 'Lennon', 'role': 'singer'}, ...];\ncrud.dataProvider = function(params, callback) {\n const chunk = users.slice(params.page * params.pageSize, params.page * params.pageSize + params.pageSize);\n callback(chunk, people.length);\n};\n```\n\nNOTE: The auto-generated editor only supports string types. If you need to handle special cases\ncustomizing the editor is discussed below.\n\n### Customization\n\nAlternatively you can fully configure the component by using `slot` names.\n\nSlot name | Description\n---------------|----------------\n`grid` | To replace the auto-generated grid with a custom one.\n`form` | To replace the auto-generated form.\n`save-button` | To replace the \"Save\" button.\n`cancel-button`| To replace the \"Cancel\" button.\n`delete-button`| To replace the \"Delete\" button.\n`toolbar` | To provide the toolbar content (by default, it's empty).\n`new-button` | To replace the \"New item\" button.\n\n#### Example:\n\n```html\n<vaadin-crud\n id=\"crud\"\n items='[{\"name\": \"John\", \"surname\": \"Lennon\", \"role\": \"singer\"},\n {\"name\": \"Ringo\", \"surname\": \"Starr\", \"role\": \"drums\"}]'\n>\n <vaadin-grid slot=\"grid\">\n <vaadin-crud-edit-column></vaadin-crud-edit-column>\n <vaadin-grid-column id=\"column1\"></vaadin-grid-column>\n <vaadin-grid-column id=\"column2\"></vaadin-grid-column>\n </vaadin-grid>\n\n <vaadin-form-layout slot=\"form\">\n <vaadin-text-field label=\"First\" path=\"name\"></vaadin-text-field>\n <vaadin-text-field label=\"Surname\" path=\"surname\"></vaadin-text-field>\n </vaadin-form-layout>\n\n <div slot=\"toolbar\">Total singers: 2</div>\n <button slot=\"new-button\">New singer</button>\n\n <button slot=\"save-button\">Save changes</button>\n <button slot=\"cancel-button\">Discard changes</button>\n <button slot=\"delete-button\">Delete singer</button>\n</vaadin-crud>\n```\n```js\nconst crud = document.querySelector('#crud');\n\nconst column1 = document.querySelector('#column1');\ncolumn1.headerRenderer = (root, column) => {\n root.textContent = 'Name';\n};\ncolumn1.renderer = (root, column, model) => {\n root.textContent = model.item.name;\n};\n\nconst column2 = document.querySelector('#column2');\ncolumn2.headerRenderer = (root, column) => {\n root.textContent = 'Surname';\n};\ncolumn2.renderer = (root, column, model) => {\n root.textContent = model.item.surname;\n};\n```\n\n### Helpers\n\nThe following elements are used to auto-configure the grid and the editor\n- [`<vaadin-crud-edit-column>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud-edit-column)\n- `<vaadin-crud-grid>` - can be replaced with custom [`<vaadin-grid>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-grid)\n- `<vaadin-crud-form>` - can be replaced with custom [`<vaadin-form-layout>`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-form-layout)\n\n### Styling\n\nThe following shadow DOM parts are available for styling:\n\nPart name | Description\n----------------|----------------\n`toolbar` | Toolbar container at the bottom. By default it contains the the `new` button\n\nThe following custom properties are available:\n\nCustom Property | Description | Default\n----------------|----------------\n--vaadin-crud-editor-max-height | max height of editor when opened on the bottom | 40%\n--vaadin-crud-editor-max-width | max width of editor when opened on the side | 40%\n\nSee [Styling Components](https://vaadin.com/docs/latest/styling/custom-theme/styling-components) documentation.",
125
125
  "extension": true,
126
126
  "attributes": [
127
127
  {
@@ -196,14 +196,14 @@
196
196
  },
197
197
  {
198
198
  "name": ".include",
199
- "description": "A comma-separated list of fields to include in the generated grid and the generated editor.\n\nIt can be used to explicitly define the field order.\n\nWhen it is defined [`exclude`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-exclude) is ignored.\n\nDefault is undefined meaning that all properties in the object should be mapped to fields.",
199
+ "description": "A comma-separated list of fields to include in the generated grid and the generated editor.\n\nIt can be used to explicitly define the field order.\n\nWhen it is defined [`exclude`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-exclude) is ignored.\n\nDefault is undefined meaning that all properties in the object should be mapped to fields.",
200
200
  "value": {
201
201
  "kind": "expression"
202
202
  }
203
203
  },
204
204
  {
205
205
  "name": ".exclude",
206
- "description": "A comma-separated list of fields to be excluded from the generated grid and the generated editor.\n\nWhen [`include`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha1/#/elements/vaadin-crud#property-include) is defined, this parameter is ignored.\n\nDefault is to exclude all private fields (those properties starting with underscore)",
206
+ "description": "A comma-separated list of fields to be excluded from the generated grid and the generated editor.\n\nWhen [`include`](https://cdn.vaadin.com/vaadin-web-components/24.0.0-alpha3/#/elements/vaadin-crud#property-include) is defined, this parameter is ignored.\n\nDefault is to exclude all private fields (those properties starting with underscore)",
207
207
  "value": {
208
208
  "kind": "expression"
209
209
  }