@vaadin/crud 22.0.0-rc1 → 23.0.0-alpha2
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 +12 -13
- package/src/vaadin-crud-dialog.js +121 -0
- package/src/vaadin-crud-edit.d.ts +2 -2
- package/src/vaadin-crud-edit.js +5 -5
- package/src/vaadin-crud-grid.js +81 -30
- package/src/vaadin-crud.js +227 -71
- package/theme/lumo/vaadin-crud-styles.js +94 -105
- package/theme/material/vaadin-crud-styles.js +84 -81
- package/src/vaadin-dialog-layout.js +0 -241
- package/theme/vaadin-dialog-layout-overlay-styles.js +0 -45
package/src/vaadin-crud.js
CHANGED
|
@@ -8,13 +8,14 @@ import '@vaadin/button/src/vaadin-button.js';
|
|
|
8
8
|
import '@vaadin/dialog/src/vaadin-dialog.js';
|
|
9
9
|
import '@vaadin/confirm-dialog/src/vaadin-confirm-dialog.js';
|
|
10
10
|
import '@vaadin/vaadin-license-checker/vaadin-license-checker.js';
|
|
11
|
-
import './vaadin-dialog
|
|
11
|
+
import './vaadin-crud-dialog.js';
|
|
12
12
|
import './vaadin-crud-grid.js';
|
|
13
13
|
import './vaadin-crud-form.js';
|
|
14
14
|
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js';
|
|
15
15
|
import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';
|
|
16
16
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
17
17
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
18
|
+
import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
|
|
18
19
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
19
20
|
|
|
20
21
|
const HOST_PROPS = {
|
|
@@ -148,9 +149,10 @@ const HOST_PROPS = {
|
|
|
148
149
|
*
|
|
149
150
|
* @extends HTMLElement
|
|
150
151
|
* @mixes ElementMixin
|
|
152
|
+
* @mixes SlotMixin
|
|
151
153
|
* @mixes ThemableMixin
|
|
152
154
|
*/
|
|
153
|
-
class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
155
|
+
class Crud extends SlotMixin(ElementMixin(ThemableMixin(PolymerElement))) {
|
|
154
156
|
static get template() {
|
|
155
157
|
return html`
|
|
156
158
|
<style>
|
|
@@ -174,7 +176,8 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
174
176
|
height: 100%;
|
|
175
177
|
}
|
|
176
178
|
|
|
177
|
-
:host([hidden])
|
|
179
|
+
:host([hidden]),
|
|
180
|
+
[hidden] {
|
|
178
181
|
display: none !important;
|
|
179
182
|
}
|
|
180
183
|
|
|
@@ -197,6 +200,39 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
197
200
|
:host([editor-position='bottom']) #container {
|
|
198
201
|
flex-direction: column;
|
|
199
202
|
}
|
|
203
|
+
|
|
204
|
+
[part='editor'] {
|
|
205
|
+
z-index: 1;
|
|
206
|
+
display: flex;
|
|
207
|
+
flex-direction: column;
|
|
208
|
+
height: 100%;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
:host(:not([editor-position=''])[editor-opened]:not([fullscreen])) [part='editor'] {
|
|
212
|
+
flex: 1 0 100%;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
:host([editor-position='bottom'][editor-opened]:not([fullscreen])) [part='editor'] {
|
|
216
|
+
max-height: var(--vaadin-crud-editor-max-height);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
:host([editor-position='aside'][editor-opened]:not([fullscreen])) [part='editor'] {
|
|
220
|
+
min-width: 300px;
|
|
221
|
+
max-width: var(--vaadin-crud-editor-max-width);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
[part='scroller'] {
|
|
225
|
+
display: flex;
|
|
226
|
+
flex-direction: column;
|
|
227
|
+
overflow: auto;
|
|
228
|
+
flex: auto;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
[part='footer'] {
|
|
232
|
+
display: flex;
|
|
233
|
+
flex: none;
|
|
234
|
+
flex-direction: row-reverse;
|
|
235
|
+
}
|
|
200
236
|
</style>
|
|
201
237
|
|
|
202
238
|
<div id="container">
|
|
@@ -220,49 +256,33 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
220
256
|
</slot>
|
|
221
257
|
</div>
|
|
222
258
|
</div>
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
no-close-on-outside-click="[[__isDirty]]"
|
|
231
|
-
no-close-on-esc="[[__isDirty]]"
|
|
232
|
-
opened="{{editorOpened}}"
|
|
233
|
-
editor-position$="{{editorPosition}}"
|
|
234
|
-
mobile="[[__mobile]]"
|
|
235
|
-
theme="crud"
|
|
236
|
-
>
|
|
237
|
-
<h3 slot="header">[[__computeEditorHeader(__isNew, i18n.newItem, i18n.editItem)]]</h3>
|
|
238
|
-
<div id="editor">
|
|
239
|
-
<slot name="form">
|
|
240
|
-
<vaadin-crud-form
|
|
241
|
-
theme$="[[theme]]"
|
|
242
|
-
id="form"
|
|
243
|
-
include="[[include]]"
|
|
244
|
-
exclude="[[exclude]]"
|
|
245
|
-
></vaadin-crud-form>
|
|
246
|
-
</slot>
|
|
259
|
+
|
|
260
|
+
<div id="editor" part="editor" hidden$="[[__computeEditorHidden(editorOpened, _fullscreen, editorPosition)]]">
|
|
261
|
+
<div part="scroller" id="scroller" role="group" aria-labelledby="header">
|
|
262
|
+
<div part="header" id="header">
|
|
263
|
+
<slot name="header"></slot>
|
|
264
|
+
</div>
|
|
265
|
+
<slot name="form"></slot>
|
|
247
266
|
</div>
|
|
248
267
|
|
|
249
|
-
<
|
|
250
|
-
<
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
</
|
|
254
|
-
|
|
255
|
-
<vaadin-button id="cancel" on-click="__cancelBound" theme="tertiary">[[i18n.cancel]]</vaadin-button>
|
|
256
|
-
</slot>
|
|
257
|
-
<div slot="footer" style="flex: auto;"></div>
|
|
258
|
-
<slot name="delete-button">
|
|
259
|
-
<vaadin-button id="delete" on-click="__delete" theme="tertiary error" hidden$="[[__isNew]]"
|
|
260
|
-
>[[i18n.deleteItem]]</vaadin-button
|
|
261
|
-
>
|
|
262
|
-
</slot>
|
|
263
|
-
</vaadin-dialog-layout>
|
|
268
|
+
<div part="footer" role="toolbar">
|
|
269
|
+
<slot name="save-button"></slot>
|
|
270
|
+
<slot name="cancel-button"></slot>
|
|
271
|
+
<slot name="delete-button"></slot>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
264
274
|
</div>
|
|
265
275
|
|
|
276
|
+
<vaadin-crud-dialog
|
|
277
|
+
id="dialog"
|
|
278
|
+
opened="[[__computeDialogOpened(editorOpened, _fullscreen, editorPosition)]]"
|
|
279
|
+
aria-label="[[__editorAriaLabel]]"
|
|
280
|
+
no-close-on-outside-click="[[__isDirty]]"
|
|
281
|
+
no-close-on-esc="[[__isDirty]]"
|
|
282
|
+
theme$="[[theme]]"
|
|
283
|
+
on-opened-changed="__onDialogOpened"
|
|
284
|
+
></vaadin-crud-dialog>
|
|
285
|
+
|
|
266
286
|
<vaadin-confirm-dialog
|
|
267
287
|
theme$="[[theme]]"
|
|
268
288
|
id="confirmCancel"
|
|
@@ -274,6 +294,7 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
274
294
|
message="[[i18n.confirm.cancel.content]]"
|
|
275
295
|
confirm-theme="primary"
|
|
276
296
|
></vaadin-confirm-dialog>
|
|
297
|
+
|
|
277
298
|
<vaadin-confirm-dialog
|
|
278
299
|
theme$="[[theme]]"
|
|
279
300
|
id="confirmDelete"
|
|
@@ -286,7 +307,7 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
286
307
|
confirm-theme="primary error"
|
|
287
308
|
></vaadin-confirm-dialog>
|
|
288
309
|
|
|
289
|
-
<iron-media-query query="[[
|
|
310
|
+
<iron-media-query query="[[_fullscreenMediaQuery]]" query-matches="{{_fullscreen}}"></iron-media-query>
|
|
290
311
|
`;
|
|
291
312
|
}
|
|
292
313
|
|
|
@@ -341,6 +362,14 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
341
362
|
observer: '__onCancelButtonChange'
|
|
342
363
|
},
|
|
343
364
|
|
|
365
|
+
/**
|
|
366
|
+
* A reference to the editor header element will be teleported to the dialog.
|
|
367
|
+
* @private
|
|
368
|
+
*/
|
|
369
|
+
_headerNode: {
|
|
370
|
+
type: HTMLElement
|
|
371
|
+
},
|
|
372
|
+
|
|
344
373
|
/**
|
|
345
374
|
* An array containing the items which will be stamped to the column template instances.
|
|
346
375
|
* @type {Array<unknown> | undefined}
|
|
@@ -450,6 +479,7 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
450
479
|
*/
|
|
451
480
|
editorOpened: {
|
|
452
481
|
type: Boolean,
|
|
482
|
+
reflectToAttribute: true,
|
|
453
483
|
notify: true,
|
|
454
484
|
observer: '__onOpenedChanged'
|
|
455
485
|
},
|
|
@@ -465,7 +495,7 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
465
495
|
},
|
|
466
496
|
|
|
467
497
|
/**
|
|
468
|
-
* Controls
|
|
498
|
+
* Controls visibility state of toolbar.
|
|
469
499
|
* When set to false toolbar is hidden and shown when set to true.
|
|
470
500
|
* @attr {boolean} no-toolbar
|
|
471
501
|
*/
|
|
@@ -546,27 +576,38 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
546
576
|
}
|
|
547
577
|
},
|
|
548
578
|
|
|
579
|
+
/** @private */
|
|
580
|
+
__editorAriaLabel: String,
|
|
581
|
+
|
|
549
582
|
/** @private */
|
|
550
583
|
__isDirty: Boolean,
|
|
551
584
|
|
|
552
585
|
/** @private */
|
|
553
586
|
__isNew: Boolean,
|
|
554
587
|
|
|
555
|
-
/**
|
|
556
|
-
|
|
557
|
-
|
|
588
|
+
/**
|
|
589
|
+
* @type {boolean}
|
|
590
|
+
* @protected
|
|
591
|
+
*/
|
|
592
|
+
_fullscreen: {
|
|
593
|
+
type: Boolean,
|
|
594
|
+
observer: '__fullscreenChanged'
|
|
558
595
|
},
|
|
559
596
|
|
|
560
|
-
/**
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
597
|
+
/**
|
|
598
|
+
* @type {string}
|
|
599
|
+
* @protected
|
|
600
|
+
*/
|
|
601
|
+
_fullscreenMediaQuery: {
|
|
602
|
+
value: '(max-width: 600px), (max-height: 600px)'
|
|
564
603
|
}
|
|
565
604
|
};
|
|
566
605
|
}
|
|
567
606
|
|
|
568
607
|
static get observers() {
|
|
569
608
|
return [
|
|
609
|
+
'__headerNodeChanged(_headerNode, __isNew, i18n.newItem, i18n.editItem)',
|
|
610
|
+
'__formChanged(_form, theme, include, exclude)',
|
|
570
611
|
'__onI18Change(i18n, _grid)',
|
|
571
612
|
'__onEditOnClickChange(editOnClick, _grid)',
|
|
572
613
|
'__hostPropsChanged(' +
|
|
@@ -590,6 +631,38 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
590
631
|
}
|
|
591
632
|
}
|
|
592
633
|
|
|
634
|
+
/** @protected */
|
|
635
|
+
get slots() {
|
|
636
|
+
// NOTE: order in which the toolbar buttons are listed matters.
|
|
637
|
+
return {
|
|
638
|
+
...super.slots,
|
|
639
|
+
header: () => {
|
|
640
|
+
return document.createElement('h3');
|
|
641
|
+
},
|
|
642
|
+
form: () => {
|
|
643
|
+
return document.createElement('vaadin-crud-form');
|
|
644
|
+
},
|
|
645
|
+
'save-button': () => {
|
|
646
|
+
const button = document.createElement('vaadin-button');
|
|
647
|
+
button.id = 'save';
|
|
648
|
+
button.setAttribute('theme', 'primary');
|
|
649
|
+
return button;
|
|
650
|
+
},
|
|
651
|
+
'cancel-button': () => {
|
|
652
|
+
const button = document.createElement('vaadin-button');
|
|
653
|
+
button.id = 'cancel';
|
|
654
|
+
button.setAttribute('theme', 'tertiary');
|
|
655
|
+
return button;
|
|
656
|
+
},
|
|
657
|
+
'delete-button': () => {
|
|
658
|
+
const button = document.createElement('vaadin-button');
|
|
659
|
+
button.id = 'delete';
|
|
660
|
+
button.setAttribute('theme', 'tertiary error');
|
|
661
|
+
return button;
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
|
|
593
666
|
constructor() {
|
|
594
667
|
super();
|
|
595
668
|
this._observer = new FlattenedNodesObserver(this, (info) => {
|
|
@@ -608,24 +681,33 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
608
681
|
this.__gridSizeListener = this.__onGridSizeChanges.bind(this);
|
|
609
682
|
this.__boundEditOnClickListener = this.__editOnClickListener.bind(this);
|
|
610
683
|
this._grid = this.$.grid;
|
|
611
|
-
this.
|
|
612
|
-
this.
|
|
613
|
-
|
|
614
|
-
this.
|
|
615
|
-
this.$.dialog.$.dialog.$.overlay.addEventListener('vaadin-overlay-outside-click', this.__cancelBound);
|
|
616
|
-
this.$.dialog.$.dialog.$.overlay.addEventListener('vaadin-overlay-escape-press', this.__cancelBound);
|
|
684
|
+
this.$.dialog.$.overlay.addEventListener('vaadin-overlay-outside-click', this.__cancelBound);
|
|
685
|
+
this.$.dialog.$.overlay.addEventListener('vaadin-overlay-escape-press', this.__cancelBound);
|
|
686
|
+
// Initialize the default buttons
|
|
687
|
+
this.__propagateHostAttributes();
|
|
617
688
|
}
|
|
618
689
|
|
|
619
690
|
/** @private */
|
|
620
691
|
__isSaveBtnDisabled(isDirty) {
|
|
621
|
-
// Used instead of isDirty
|
|
692
|
+
// Used instead of isDirty property binding in order to enable overriding of the behavior
|
|
622
693
|
// by overriding the method (i.e. from Flow component)
|
|
623
694
|
return !isDirty;
|
|
624
695
|
}
|
|
625
696
|
|
|
626
697
|
/** @private */
|
|
627
|
-
|
|
628
|
-
|
|
698
|
+
__headerNodeChanged(headerNode, isNew, newItem, editItem) {
|
|
699
|
+
if (headerNode) {
|
|
700
|
+
headerNode.textContent = isNew ? newItem : editItem;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
/** @private */
|
|
705
|
+
__formChanged(form, theme, include, exclude) {
|
|
706
|
+
if (form) {
|
|
707
|
+
form.include = include;
|
|
708
|
+
form.exclude = exclude;
|
|
709
|
+
form.setAttribute('theme', theme);
|
|
710
|
+
}
|
|
629
711
|
}
|
|
630
712
|
|
|
631
713
|
/** @private */
|
|
@@ -662,26 +744,99 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
662
744
|
this.__onFormChange(this._form);
|
|
663
745
|
}
|
|
664
746
|
|
|
747
|
+
if (opened) {
|
|
748
|
+
this.__ensureChildren();
|
|
749
|
+
}
|
|
750
|
+
|
|
665
751
|
this.__toggleToolbar();
|
|
752
|
+
|
|
753
|
+
// Make sure to reset scroll position
|
|
754
|
+
this.$.scroller.scrollTop = 0;
|
|
666
755
|
}
|
|
667
756
|
|
|
668
757
|
/** @private */
|
|
669
|
-
|
|
670
|
-
|
|
758
|
+
__fullscreenChanged(fullscreen, oldFullscreen) {
|
|
759
|
+
if (fullscreen || oldFullscreen) {
|
|
760
|
+
this.__toggleToolbar();
|
|
761
|
+
|
|
762
|
+
this.__ensureChildren();
|
|
763
|
+
|
|
764
|
+
this.toggleAttribute('fullscreen', fullscreen);
|
|
765
|
+
this.$.dialog.$.overlay.toggleAttribute('fullscreen', fullscreen);
|
|
766
|
+
}
|
|
671
767
|
}
|
|
672
768
|
|
|
673
769
|
/** @private */
|
|
674
770
|
__toggleToolbar() {
|
|
675
771
|
// Hide toolbar to give more room for the editor when it's positioned below the grid
|
|
676
|
-
if (this.editorPosition === 'bottom' && !this.
|
|
772
|
+
if (this.editorPosition === 'bottom' && !this._fullscreen) {
|
|
677
773
|
this.$.toolbar.style.display = this.editorOpened ? 'none' : '';
|
|
678
774
|
}
|
|
679
775
|
}
|
|
680
776
|
|
|
681
777
|
/** @private */
|
|
682
|
-
|
|
778
|
+
__moveChildNodes(target) {
|
|
779
|
+
const nodes = [this._headerNode, this._form, this._saveButton, this._cancelButton, this._deleteButton];
|
|
780
|
+
if (!nodes.every((node) => node instanceof HTMLElement)) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
// Teleport header node, form, and the buttons to corresponding slots.
|
|
785
|
+
// NOTE: order in which buttons are moved matches the order of slots.
|
|
683
786
|
nodes.forEach((node) => {
|
|
684
|
-
|
|
787
|
+
target.appendChild(node);
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
// Wait to set label until slotted element has been moved.
|
|
791
|
+
setTimeout(() => {
|
|
792
|
+
this.__dialogAriaLabel = this._headerNode.textContent.trim();
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/** @private */
|
|
797
|
+
__shouldOpenDialog(fullscreen, editorPosition) {
|
|
798
|
+
return editorPosition === '' || fullscreen;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/** @private */
|
|
802
|
+
__ensureChildren() {
|
|
803
|
+
if (this.__shouldOpenDialog(this._fullscreen, this.editorPosition)) {
|
|
804
|
+
// Move form to dialog
|
|
805
|
+
this.__moveChildNodes(this.$.dialog.$.overlay);
|
|
806
|
+
} else {
|
|
807
|
+
// Move form to crud
|
|
808
|
+
this.__moveChildNodes(this);
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
/** @private */
|
|
813
|
+
__computeDialogOpened(opened, fullscreen, editorPosition) {
|
|
814
|
+
// Only open dialog when editorPosition is "" or fullscreen is set
|
|
815
|
+
return this.__shouldOpenDialog(fullscreen, editorPosition) ? opened : false;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
/** @private */
|
|
819
|
+
__computeEditorHidden(opened, fullscreen, editorPosition) {
|
|
820
|
+
// Only show editor when editorPosition is "bottom" or "aside"
|
|
821
|
+
if (['aside', 'bottom'].includes(editorPosition) && !fullscreen) {
|
|
822
|
+
return !opened;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
return true;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/** @private */
|
|
829
|
+
__onDialogOpened(event) {
|
|
830
|
+
this.editorOpened = event.detail.value;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/** @private */
|
|
834
|
+
__onDomChange(addedNodes) {
|
|
835
|
+
// TODO: restore default button when a corresponding slotted button is removed.
|
|
836
|
+
// Consider creating a controller to reuse custom helper logic from FieldMixin.
|
|
837
|
+
addedNodes
|
|
838
|
+
.filter((node) => node.nodeType === Node.ELEMENT_NODE)
|
|
839
|
+
.forEach((node) => {
|
|
685
840
|
const slotAttributeValue = node.getAttribute('slot');
|
|
686
841
|
if (!slotAttributeValue) {
|
|
687
842
|
return;
|
|
@@ -697,9 +852,10 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
697
852
|
} else if (slotAttributeValue.indexOf('button') >= 0) {
|
|
698
853
|
const [button] = slotAttributeValue.split('-');
|
|
699
854
|
this[`_${button}Button`] = node;
|
|
855
|
+
} else if (slotAttributeValue == 'header') {
|
|
856
|
+
this._headerNode = node;
|
|
700
857
|
}
|
|
701
|
-
}
|
|
702
|
-
});
|
|
858
|
+
});
|
|
703
859
|
}
|
|
704
860
|
|
|
705
861
|
/** @private */
|
|
@@ -776,9 +932,7 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
776
932
|
currentButton.parentElement.removeChild(currentButton);
|
|
777
933
|
}
|
|
778
934
|
|
|
779
|
-
|
|
780
|
-
slottedButton.addEventListener('click', clickListener);
|
|
781
|
-
}
|
|
935
|
+
slottedButton.addEventListener('click', clickListener);
|
|
782
936
|
}
|
|
783
937
|
|
|
784
938
|
/** @private */
|
|
@@ -795,6 +949,8 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
795
949
|
|
|
796
950
|
/** @private */
|
|
797
951
|
__propagateHostAttributesToButton(button, props) {
|
|
952
|
+
// Ensure the slotted button element is present in the DOM.
|
|
953
|
+
// This is needed because the observer runs before `ready`.
|
|
798
954
|
if (button) {
|
|
799
955
|
props.forEach(({ attr, prop, parseProp }) => {
|
|
800
956
|
if (prop.indexOf('i18n') >= 0) {
|
|
@@ -1017,7 +1173,7 @@ class Crud extends ElementMixin(ThemableMixin(PolymerElement)) {
|
|
|
1017
1173
|
return;
|
|
1018
1174
|
}
|
|
1019
1175
|
|
|
1020
|
-
const item =
|
|
1176
|
+
const item = { ...this.editedItem };
|
|
1021
1177
|
this._fields.forEach((e) => {
|
|
1022
1178
|
const path = e.path || e.getAttribute('path');
|
|
1023
1179
|
path && this.__set(path, e.value, item);
|