@vaadin/crud 24.8.4 → 25.0.0-alpha10

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.
Files changed (46) hide show
  1. package/README.md +0 -23
  2. package/package.json +19 -20
  3. package/src/{vaadin-crud-styles.d.ts → styles/vaadin-crud-base-styles.d.ts} +0 -2
  4. package/src/styles/vaadin-crud-base-styles.js +162 -0
  5. package/src/styles/vaadin-crud-core-styles.d.ts +13 -0
  6. package/src/{vaadin-crud-styles.js → styles/vaadin-crud-core-styles.js} +1 -33
  7. package/src/styles/vaadin-crud-dialog-overlay-base-styles.d.ts +13 -0
  8. package/src/styles/vaadin-crud-dialog-overlay-base-styles.js +48 -0
  9. package/src/styles/vaadin-crud-dialog-overlay-core-styles.d.ts +13 -0
  10. package/src/styles/vaadin-crud-dialog-overlay-core-styles.js +54 -0
  11. package/src/styles/vaadin-crud-edit-base-styles.js +28 -0
  12. package/src/styles/vaadin-crud-edit-core-styles.js +17 -0
  13. package/src/styles/vaadin-crud-grid-base-styles.d.ts +13 -0
  14. package/src/styles/vaadin-crud-grid-base-styles.js +21 -0
  15. package/src/styles/vaadin-crud-grid-core-styles.d.ts +13 -0
  16. package/src/styles/vaadin-crud-grid-core-styles.js +13 -0
  17. package/src/vaadin-crud-controllers.js +1 -1
  18. package/src/vaadin-crud-dialog.js +72 -41
  19. package/src/vaadin-crud-edit.js +12 -21
  20. package/src/vaadin-crud-form.js +4 -1
  21. package/src/vaadin-crud-grid.js +5 -0
  22. package/src/vaadin-crud-mixin.js +67 -81
  23. package/src/vaadin-crud.d.ts +18 -8
  24. package/src/vaadin-crud.js +126 -66
  25. package/web-types.json +6 -6
  26. package/web-types.lit.json +4 -4
  27. package/src/vaadin-lit-crud-dialog.js +0 -128
  28. package/src/vaadin-lit-crud-edit-column.js +0 -70
  29. package/src/vaadin-lit-crud-edit.js +0 -75
  30. package/src/vaadin-lit-crud-form.js +0 -80
  31. package/src/vaadin-lit-crud-grid.js +0 -35
  32. package/src/vaadin-lit-crud.js +0 -121
  33. package/theme/lumo/vaadin-lit-crud.d.ts +0 -8
  34. package/theme/lumo/vaadin-lit-crud.js +0 -8
  35. package/theme/material/vaadin-crud-styles.d.ts +0 -2
  36. package/theme/material/vaadin-crud-styles.js +0 -157
  37. package/theme/material/vaadin-crud.d.ts +0 -8
  38. package/theme/material/vaadin-crud.js +0 -8
  39. package/theme/material/vaadin-lit-crud.d.ts +0 -8
  40. package/theme/material/vaadin-lit-crud.js +0 -8
  41. package/vaadin-lit-crud-edit .js +0 -1
  42. package/vaadin-lit-crud-edit-column.d.ts +0 -1
  43. package/vaadin-lit-crud-edit-column.js +0 -1
  44. package/vaadin-lit-crud-edit.d.ts +0 -1
  45. package/vaadin-lit-crud.d.ts +0 -1
  46. package/vaadin-lit-crud.js +0 -2
@@ -8,25 +8,18 @@
8
8
  * See https://vaadin.com/commercial-license-and-service-terms for the full
9
9
  * license.
10
10
  */
11
- import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
11
+ import { css, html, LitElement } from 'lit';
12
+ import { ifDefined } from 'lit/directives/if-defined.js';
12
13
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
13
14
  import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
14
15
  import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
16
+ import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
15
17
  import { DialogBaseMixin } from '@vaadin/dialog/src/vaadin-dialog-base-mixin.js';
16
- import { dialogOverlay, resizableOverlay } from '@vaadin/dialog/src/vaadin-dialog-styles.js';
17
18
  import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
18
- import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
19
- import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
19
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
20
+ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
20
21
  import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
21
- import { crudDialogOverlayStyles } from './vaadin-crud-styles.js';
22
-
23
- registerStyles(
24
- 'vaadin-crud-dialog-overlay',
25
- [overlayStyles, dialogOverlay, resizableOverlay, crudDialogOverlayStyles],
26
- {
27
- moduleId: 'vaadin-crud-dialog-overlay-styles',
28
- },
29
- );
22
+ import { crudDialogOverlayStyles } from './styles/vaadin-crud-dialog-overlay-core-styles.js';
30
23
 
31
24
  /**
32
25
  * An element used internally by `<vaadin-crud>`. Not intended to be used separately.
@@ -38,17 +31,33 @@ registerStyles(
38
31
  * @mixes ThemableMixin
39
32
  * @private
40
33
  */
41
- class CrudDialogOverlay extends OverlayMixin(DirMixin(ThemableMixin(PolymerElement))) {
34
+ class CrudDialogOverlay extends OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))) {
42
35
  static get is() {
43
36
  return 'vaadin-crud-dialog-overlay';
44
37
  }
45
38
 
46
- static get template() {
39
+ static get styles() {
40
+ return crudDialogOverlayStyles;
41
+ }
42
+
43
+ /**
44
+ * Override method from OverlayFocusMixin to use the owner (CRUD element) as modal root
45
+ * @protected
46
+ * @override
47
+ */
48
+ get _modalRoot() {
49
+ return this.owner;
50
+ }
51
+
52
+ /** @protected */
53
+ render() {
47
54
  return html`
48
- <div part="backdrop" id="backdrop" hidden$="[[!withBackdrop]]"></div>
55
+ <div part="backdrop" id="backdrop" ?hidden="${!this.withBackdrop}"></div>
49
56
  <div part="overlay" id="overlay" tabindex="0">
50
57
  <section id="resizerContainer" class="resizer-container">
51
- <header part="header"><slot name="header"></slot></header>
58
+ <header part="header">
59
+ <slot name="header"></slot>
60
+ </header>
52
61
  <div part="content" id="content">
53
62
  <slot name="form"></slot>
54
63
  </div>
@@ -81,48 +90,70 @@ defineCustomElement(CrudDialogOverlay);
81
90
  * An element used internally by `<vaadin-crud>`. Not intended to be used separately.
82
91
  * @private
83
92
  */
84
- class CrudDialog extends DialogBaseMixin(OverlayClassMixin(ThemePropertyMixin(PolymerElement))) {
93
+ class CrudDialog extends DialogBaseMixin(OverlayClassMixin(ThemePropertyMixin(PolylitMixin(LitElement)))) {
85
94
  static get is() {
86
95
  return 'vaadin-crud-dialog';
87
96
  }
88
97
 
98
+ static get styles() {
99
+ return css`
100
+ :host([opened]),
101
+ :host([opening]),
102
+ :host([closing]) {
103
+ display: contents !important;
104
+ }
105
+
106
+ :host,
107
+ :host([hidden]) {
108
+ display: none !important;
109
+ }
110
+ `;
111
+ }
112
+
89
113
  static get properties() {
90
114
  return {
91
- ariaLabel: {
92
- type: String,
93
- },
94
-
95
115
  fullscreen: {
96
116
  type: Boolean,
97
117
  },
118
+
119
+ crudElement: {
120
+ type: Object,
121
+ },
98
122
  };
99
123
  }
100
124
 
101
- static get template() {
125
+ /** @protected */
126
+ render() {
102
127
  return html`
103
- <style>
104
- :host {
105
- display: none;
106
- }
107
- </style>
108
-
109
128
  <vaadin-crud-dialog-overlay
110
129
  id="overlay"
111
- opened="[[opened]]"
112
- aria-label$="[[ariaLabel]]"
113
- on-opened-changed="_onOverlayOpened"
114
- on-mousedown="_bringOverlayToFront"
115
- on-touchstart="_bringOverlayToFront"
116
- theme$="[[_theme]]"
117
- modeless="[[modeless]]"
118
- with-backdrop="[[!modeless]]"
119
- resizable$="[[resizable]]"
120
- fullscreen$="[[fullscreen]]"
121
- role="dialog"
130
+ .owner="${this.crudElement}"
131
+ .opened="${this.opened}"
132
+ @opened-changed="${this._onOverlayOpened}"
133
+ @mousedown="${this._bringOverlayToFront}"
134
+ @touchstart="${this._bringOverlayToFront}"
135
+ @vaadin-overlay-outside-click="${this.__cancel}"
136
+ @vaadin-overlay-escape-press="${this.__cancel}"
137
+ theme="${ifDefined(this._theme)}"
138
+ .modeless="${this.modeless}"
139
+ .withBackdrop="${!this.modeless}"
140
+ ?fullscreen="${this.fullscreen}"
122
141
  focus-trap
123
- ></vaadin-crud-dialog-overlay>
142
+ exportparts="backdrop, overlay, header, content, footer"
143
+ >
144
+ <slot name="header" slot="header"></slot>
145
+ <slot name="form" slot="form"></slot>
146
+ <slot name="save-button" slot="save-button"></slot>
147
+ <slot name="cancel-button" slot="cancel-button"></slot>
148
+ <slot name="delete-button" slot="delete-button"></slot>
149
+ </vaadin-crud-dialog-overlay>
124
150
  `;
125
151
  }
152
+
153
+ /** @private **/
154
+ __cancel() {
155
+ this.dispatchEvent(new CustomEvent('cancel'));
156
+ }
126
157
  }
127
158
 
128
159
  defineCustomElement(CrudDialog);
@@ -8,24 +8,10 @@
8
8
  * See https://vaadin.com/commercial-license-and-service-terms for the full
9
9
  * license.
10
10
  */
11
- import { html } from '@polymer/polymer/polymer-element.js';
11
+ import { html } from 'lit';
12
12
  import { Button } from '@vaadin/button/src/vaadin-button.js';
13
13
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
14
- import { css, registerStyles } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
15
-
16
- /**
17
- * Use registerStyles instead of the `<style>` tag to make sure
18
- * that this CSS will override core styles of `vaadin-button`.
19
- */
20
- registerStyles(
21
- 'vaadin-crud-edit',
22
- css`
23
- :host {
24
- display: block;
25
- }
26
- `,
27
- { moduleId: 'vaadin-crud-edit-styles' },
28
- );
14
+ import { crudEditStyles } from './styles/vaadin-crud-edit-core-styles.js';
29
15
 
30
16
  /**
31
17
  * `<vaadin-crud-edit>` is a helper element for `<vaadin-grid-column>` that provides
@@ -40,17 +26,22 @@ registerStyles(
40
26
  * @mixes ThemableMixin
41
27
  */
42
28
  class CrudEdit extends Button {
43
- static get template() {
29
+ static get is() {
30
+ return 'vaadin-crud-edit';
31
+ }
32
+
33
+ static get styles() {
34
+ return [super.styles, crudEditStyles];
35
+ }
36
+
37
+ /** @protected */
38
+ render() {
44
39
  return html`
45
40
  <div part="icon"></div>
46
41
  <slot name="tooltip"></slot>
47
42
  `;
48
43
  }
49
44
 
50
- static get is() {
51
- return 'vaadin-crud-edit';
52
- }
53
-
54
45
  /** @protected */
55
46
  ready() {
56
47
  super.ready();
@@ -33,7 +33,10 @@ class CrudForm extends IncludedMixin(FormLayout) {
33
33
  * The item being edited.
34
34
  * @type {unknown}
35
35
  */
36
- item: Object,
36
+ item: {
37
+ type: Object,
38
+ sync: true,
39
+ },
37
40
  };
38
41
  }
39
42
 
@@ -15,6 +15,7 @@ import '@vaadin/grid/src/vaadin-grid-sorter.js';
15
15
  import './vaadin-crud-edit-column.js';
16
16
  import { defineCustomElement } from '@vaadin/component-base/src/define.js';
17
17
  import { Grid } from '@vaadin/grid/src/vaadin-grid.js';
18
+ import { crudGridStyles } from './styles/vaadin-crud-grid-core-styles.js';
18
19
  import { CrudGridMixin } from './vaadin-crud-grid-mixin.js';
19
20
 
20
21
  /**
@@ -28,6 +29,10 @@ class CrudGrid extends CrudGridMixin(Grid) {
28
29
  static get is() {
29
30
  return 'vaadin-crud-grid';
30
31
  }
32
+
33
+ static get styles() {
34
+ return crudGridStyles;
35
+ }
31
36
  }
32
37
 
33
38
  defineCustomElement(CrudGrid);
@@ -377,12 +377,31 @@ export const CrudMixin = (superClass) =>
377
377
  return this.__fields;
378
378
  }
379
379
 
380
+ /** @private */
381
+ get _editor() {
382
+ return this.shadowRoot.querySelector('#editor');
383
+ }
384
+
385
+ /** @private */
386
+ get _scroller() {
387
+ return this.shadowRoot.querySelector('#scroller');
388
+ }
389
+
390
+ /** @private */
391
+ get _dialogMode() {
392
+ return this.editorPosition === '' || this._fullscreen;
393
+ }
394
+
380
395
  /** @protected */
381
396
  ready() {
382
397
  super.ready();
383
398
 
384
- this.$.dialog.$.overlay.addEventListener('vaadin-overlay-outside-click', this.__cancel);
385
- this.$.dialog.$.overlay.addEventListener('vaadin-overlay-escape-press', this.__cancel);
399
+ this._gridController = new GridSlotController(this);
400
+ this.addController(this._gridController);
401
+
402
+ // Init button controllers in `ready()` (not constructor) so that Flow can set `_noDefaultButtons`
403
+ this._newButtonController = new ButtonSlotController(this, 'new', null, this._noDefaultButtons);
404
+ this.addController(this._newButtonController);
386
405
 
387
406
  this._headerController = new SlotController(this, 'header', 'h3', {
388
407
  initializer: (node) => {
@@ -391,19 +410,12 @@ export const CrudMixin = (superClass) =>
391
410
  });
392
411
  this.addController(this._headerController);
393
412
 
394
- this._gridController = new GridSlotController(this);
395
- this.addController(this._gridController);
396
-
397
413
  this.addController(new FormSlotController(this));
398
414
 
399
- // Init controllers in `ready()` (not constructor) so that Flow can set `_noDefaultButtons`
400
- this._newButtonController = new ButtonSlotController(this, 'new', 'primary', this._noDefaultButtons);
401
415
  this._saveButtonController = new ButtonSlotController(this, 'save', 'primary', this._noDefaultButtons);
402
416
  this._cancelButtonController = new ButtonSlotController(this, 'cancel', 'tertiary', this._noDefaultButtons);
403
417
  this._deleteButtonController = new ButtonSlotController(this, 'delete', 'tertiary error', this._noDefaultButtons);
404
418
 
405
- this.addController(this._newButtonController);
406
-
407
419
  // NOTE: order in which buttons are added should match the order of slots in template
408
420
  this.addController(this._saveButtonController);
409
421
  this.addController(this._cancelButtonController);
@@ -416,6 +428,27 @@ export const CrudMixin = (superClass) =>
416
428
  );
417
429
 
418
430
  this.addController(this.__focusRestorationController);
431
+
432
+ this._confirmCancelDialog = this.querySelector('vaadin-confirm-dialog[slot="confirm-cancel"]');
433
+ this._confirmDeleteDialog = this.querySelector('vaadin-confirm-dialog[slot="confirm-delete"]');
434
+ }
435
+
436
+ /** @protected */
437
+ updated(props) {
438
+ super.updated(props);
439
+
440
+ // When using dialog mode, hide elements not slotted into the dialog from accessibility tree
441
+ if (
442
+ props.has('_grid') ||
443
+ props.has('_newButton') ||
444
+ props.has('editorOpened') ||
445
+ props.has('editorPosition') ||
446
+ props.has('_fullscreen')
447
+ ) {
448
+ const hide = this.editorOpened && this._dialogMode;
449
+ this.__hideElement(this._grid, hide);
450
+ this.__hideElement(this._newButton, hide);
451
+ }
419
452
  }
420
453
 
421
454
  /**
@@ -474,22 +507,24 @@ export const CrudMixin = (superClass) =>
474
507
  }
475
508
 
476
509
  if (opened) {
477
- this.__ensureChildren();
478
-
479
510
  // When using bottom / aside editor position,
480
511
  // auto-focus the editor element on open.
481
- if (this._form.parentElement === this) {
482
- this.$.editor.setAttribute('tabindex', '0');
483
- this.$.editor.focus();
484
- } else {
485
- this.$.editor.removeAttribute('tabindex');
512
+ if (this._editor) {
513
+ this._editor.focus();
486
514
  }
515
+
516
+ // Wait to set label until header node has updated (observer seems to run after this one)
517
+ setTimeout(() => {
518
+ this.__dialogAriaLabel = this._headerNode.textContent.trim();
519
+ });
487
520
  }
488
521
 
489
522
  this.__toggleToolbar();
490
523
 
491
524
  // Make sure to reset scroll position
492
- this.$.scroller.scrollTop = 0;
525
+ if (this._scroller) {
526
+ this._scroller.scrollTop = 0;
527
+ }
493
528
  }
494
529
 
495
530
  /** @private */
@@ -497,8 +532,6 @@ export const CrudMixin = (superClass) =>
497
532
  if (fullscreen || oldFullscreen) {
498
533
  this.__toggleToolbar();
499
534
 
500
- this.__ensureChildren();
501
-
502
535
  this.toggleAttribute('fullscreen', fullscreen);
503
536
  }
504
537
  }
@@ -511,63 +544,6 @@ export const CrudMixin = (superClass) =>
511
544
  }
512
545
  }
513
546
 
514
- /** @private */
515
- __moveChildNodes(target) {
516
- const nodes = [this._headerNode, this._form];
517
- const buttons = [this._saveButton, this._cancelButton, this._deleteButton].filter(Boolean);
518
- if (!nodes.every((node) => node instanceof HTMLElement)) {
519
- return;
520
- }
521
-
522
- // Teleport header node, form, and the buttons to corresponding slots.
523
- // NOTE: order in which buttons are moved matches the order of slots.
524
- [...nodes, ...buttons].forEach((node) => {
525
- target.appendChild(node);
526
- });
527
-
528
- // Wait to set label until slotted element has been moved.
529
- setTimeout(() => {
530
- this.__dialogAriaLabel = this._headerNode.textContent.trim();
531
- });
532
- }
533
-
534
- /** @private */
535
- __shouldOpenDialog(fullscreen, editorPosition) {
536
- return editorPosition === '' || fullscreen;
537
- }
538
-
539
- /** @private */
540
- __ensureChildren() {
541
- if (this.__shouldOpenDialog(this._fullscreen, this.editorPosition)) {
542
- // Move form to dialog
543
- this.__moveChildNodes(this.$.dialog.$.overlay);
544
- } else {
545
- // Move form to crud
546
- this.__moveChildNodes(this);
547
- }
548
- }
549
-
550
- /** @private */
551
- __computeDialogOpened(opened, fullscreen, editorPosition) {
552
- // Only open dialog when editorPosition is "" or fullscreen is set
553
- return this.__shouldOpenDialog(fullscreen, editorPosition) ? opened : false;
554
- }
555
-
556
- /** @private */
557
- __computeEditorHidden(opened, fullscreen, editorPosition) {
558
- // Only show editor when editorPosition is "bottom" or "aside"
559
- if (['aside', 'bottom'].includes(editorPosition) && !fullscreen) {
560
- return !opened;
561
- }
562
-
563
- return true;
564
- }
565
-
566
- /** @private */
567
- __onDialogOpened(event) {
568
- this.editorOpened = event.detail.value;
569
- }
570
-
571
547
  /** @private */
572
548
  __onGridEdit(event) {
573
549
  event.stopPropagation();
@@ -611,8 +587,7 @@ export const CrudMixin = (superClass) =>
611
587
  * @private
612
588
  */
613
589
  __formChanged(form, oldForm) {
614
- if (oldForm && oldForm.parentElement) {
615
- oldForm.parentElement.removeChild(oldForm);
590
+ if (oldForm) {
616
591
  oldForm.removeEventListener('change', this.__onFormChange);
617
592
  oldForm.removeEventListener('input', this.__onFormChange);
618
593
  }
@@ -780,7 +755,7 @@ export const CrudMixin = (superClass) =>
780
755
  this.__isDirty && // Form change has been made
781
756
  this.editedItem !== item // Item is different
782
757
  ) {
783
- this.$.confirmCancel.opened = true;
758
+ this._confirmCancelDialog.opened = true;
784
759
  this.addEventListener(
785
760
  'cancel',
786
761
  (event) => {
@@ -980,7 +955,7 @@ export const CrudMixin = (superClass) =>
980
955
  /** @private */
981
956
  __cancel() {
982
957
  if (this.__isDirty) {
983
- this.$.confirmCancel.opened = true;
958
+ this._confirmCancelDialog.opened = true;
984
959
  } else {
985
960
  this.__confirmCancel();
986
961
  }
@@ -997,7 +972,7 @@ export const CrudMixin = (superClass) =>
997
972
 
998
973
  /** @private */
999
974
  __delete() {
1000
- this.$.confirmDelete.opened = true;
975
+ this._confirmDeleteDialog.opened = true;
1001
976
  }
1002
977
 
1003
978
  /** @private */
@@ -1014,6 +989,17 @@ export const CrudMixin = (superClass) =>
1014
989
  }
1015
990
  }
1016
991
 
992
+ /** @private */
993
+ __hideElement(element, value) {
994
+ if (!element) return;
995
+
996
+ if (value) {
997
+ element.setAttribute('aria-hidden', 'true');
998
+ } else {
999
+ element.removeAttribute('aria-hidden');
1000
+ }
1001
+ }
1002
+
1017
1003
  /**
1018
1004
  * Fired when user wants to edit an existing item. If the default is prevented, then
1019
1005
  * a new item is not assigned to the form, giving that responsibility to the app, though
@@ -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 type { ControllerMixinClass } from '@vaadin/component-base/src/controller-mixin.js';
12
11
  import type { ElementMixinClass } from '@vaadin/component-base/src/element-mixin.js';
13
12
  import type { GridDefaultItem } from '@vaadin/grid/src/vaadin-grid.js';
14
13
  import type { ThemableMixinClass } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
@@ -133,11 +132,26 @@ export * from './vaadin-crud-mixin.js';
133
132
  *
134
133
  * ### Styling
135
134
  *
136
- * The following shadow DOM parts are available for styling:
135
+ * The following shadow DOM parts are available for styling when the editor is rendered next to, or below, the grid:
137
136
  *
138
137
  * Part name | Description
139
138
  * ----------------|----------------
140
- * `toolbar` | Toolbar container at the bottom. By default it contains the the `new` button
139
+ * `toolbar` | Toolbar container at the bottom of the grid. By default, it contains the `new` button
140
+ * `editor` | The editor container
141
+ * `scroller` | The wrapper for the header and the form
142
+ * `header` | The header of the editor
143
+ * `footer` | The footer of the editor
144
+ *
145
+ * The following shadow DOM parts are available for styling when the editor renders as a dialog:
146
+ *
147
+ * Part name | Description
148
+ * ----------------|----------------
149
+ * `toolbar` | Toolbar container at the bottom of the grid. By default, it contains the `new` button
150
+ * `overlay` | The dialog overlay
151
+ * `backdrop` | The dialog backdrop
152
+ * `header` | The header of the dialog
153
+ * `footer` | The footer of the dialog
154
+ * `content` | The wrapper for the form
141
155
  *
142
156
  * The following custom properties are available:
143
157
  *
@@ -172,11 +186,7 @@ declare class Crud<Item = GridDefaultItem> extends HTMLElement {
172
186
  ): void;
173
187
  }
174
188
 
175
- interface Crud<Item = GridDefaultItem>
176
- extends ElementMixinClass,
177
- ThemableMixinClass,
178
- ControllerMixinClass,
179
- CrudMixinClass<Item> {}
189
+ interface Crud<Item = GridDefaultItem> extends ElementMixinClass, ThemableMixinClass, CrudMixinClass<Item> {}
180
190
 
181
191
  declare global {
182
192
  interface HTMLElementTagNameMap {