Skip to content

Commit 242df2b

Browse files
authored
experiment: add LitElement based version of vaadin-crud (#8346)
1 parent 2860b7c commit 242df2b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+684
-51
lines changed

packages/crud/src/vaadin-crud-edit-column.js

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import './vaadin-crud-edit.js';
1212
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
1313
import { GridColumn } from '@vaadin/grid/src/vaadin-grid-column.js';
14+
import { editColumnDefaultRenderer } from './vaadin-crud-helpers.js';
1415

1516
/**
1617
* `<vaadin-crud-edit-column>` is a helper element for the `<vaadin-grid>`
@@ -69,21 +70,8 @@ class CrudEditColumn extends GridColumn {
6970
*
7071
* @override
7172
*/
72-
_defaultRenderer(root, _column) {
73-
let edit = root.firstElementChild;
74-
if (!edit) {
75-
edit = document.createElement('vaadin-crud-edit');
76-
if (this.hasAttribute('theme')) {
77-
edit.setAttribute('theme', this.getAttribute('theme'));
78-
}
79-
root.appendChild(edit);
80-
}
81-
82-
if (this.ariaLabel) {
83-
edit.setAttribute('aria-label', this.ariaLabel);
84-
} else {
85-
edit.removeAttribute('aria-label');
86-
}
73+
_defaultRenderer(root, column) {
74+
editColumnDefaultRenderer(root, column);
8775
}
8876
}
8977

packages/crud/src/vaadin-crud-form.js

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import '@vaadin/text-field/src/vaadin-text-field.js';
1212
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
1313
import { FormLayout } from '@vaadin/form-layout/src/vaadin-form-layout.js';
14-
import { capitalize } from './vaadin-crud-helpers.js';
14+
import { createField, createFields } from './vaadin-crud-helpers.js';
1515
import { IncludedMixin } from './vaadin-crud-include-mixin.js';
1616

1717
/**
@@ -64,31 +64,12 @@ class CrudForm extends IncludedMixin(FormLayout) {
6464

6565
/** @private */
6666
__createField(parent, path) {
67-
const field = document.createElement('vaadin-text-field');
68-
field.label = capitalize(path);
69-
field.path = path;
70-
field.required = true;
71-
parent.appendChild(field);
72-
this._fields.push(field);
73-
return field;
67+
return createField(this, parent, path);
7468
}
7569

7670
/** @private */
7771
__createFields(parent, object, path) {
78-
Object.keys(object).forEach((prop) => {
79-
if (!this.include && this.exclude && this.exclude.test(prop)) {
80-
return;
81-
}
82-
const newPath = (path ? `${path}.` : '') + prop;
83-
if (object[prop] && typeof object[prop] === 'object') {
84-
this.__createFields(parent, object[prop], newPath);
85-
} else {
86-
this.__createField(parent, newPath);
87-
}
88-
});
89-
if (!this._fields.length) {
90-
this._fields = undefined;
91-
}
72+
return createFields(this, parent, object, path);
9273
}
9374
}
9475

packages/crud/src/vaadin-crud-grid-mixin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const CrudGridMixin = (superClass) =>
4545
*/
4646
hideEditColumn: {
4747
type: Boolean,
48+
sync: true,
4849
},
4950
};
5051
}

packages/crud/src/vaadin-crud-helpers.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,47 @@ export function setProperty(path, value, obj) {
6666
export function isValidEditorPosition(editorPosition) {
6767
return ['bottom', 'aside'].includes(editorPosition);
6868
}
69+
70+
export function editColumnDefaultRenderer(root, column) {
71+
let edit = root.firstElementChild;
72+
if (!edit) {
73+
edit = document.createElement('vaadin-crud-edit');
74+
if (column.hasAttribute('theme')) {
75+
edit.setAttribute('theme', column.getAttribute('theme'));
76+
}
77+
root.appendChild(edit);
78+
}
79+
80+
if (column.ariaLabel) {
81+
edit.setAttribute('aria-label', column.ariaLabel);
82+
} else {
83+
edit.removeAttribute('aria-label');
84+
}
85+
}
86+
87+
export function createField(crudForm, parent, path) {
88+
const field = document.createElement('vaadin-text-field');
89+
field.label = capitalize(path);
90+
field.path = path;
91+
field.required = true;
92+
parent.appendChild(field);
93+
crudForm._fields.push(field);
94+
return field;
95+
}
96+
97+
export function createFields(crudForm, parent, object, path) {
98+
Object.keys(object).forEach((prop) => {
99+
if (!crudForm.include && crudForm.exclude && crudForm.exclude.test(prop)) {
100+
return;
101+
}
102+
const newPath = (path ? `${path}.` : '') + prop;
103+
if (object[prop] && typeof object[prop] === 'object') {
104+
createFields(crudForm, parent, object[prop], newPath);
105+
} else {
106+
createField(crudForm, parent, newPath);
107+
}
108+
});
109+
if (!crudForm._fields.length) {
110+
crudForm._fields = undefined;
111+
}
112+
}

packages/crud/src/vaadin-crud-include-mixin.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export const IncludedMixin = (superClass) =>
2929
exclude: {
3030
value: '^_',
3131
observer: '__onExcludeChange',
32+
sync: true,
3233
},
3334

3435
/**
@@ -40,6 +41,7 @@ export const IncludedMixin = (superClass) =>
4041
*/
4142
include: {
4243
observer: '__onIncludeChange',
44+
sync: true,
4345
},
4446
};
4547
}

packages/crud/src/vaadin-crud-mixin.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export const CrudMixin = (superClass) =>
100100
type: Object,
101101
observer: '__editedItemChanged',
102102
notify: true,
103+
sync: true,
103104
},
104105

105106
/**
@@ -117,6 +118,7 @@ export const CrudMixin = (superClass) =>
117118
value: '',
118119
reflectToAttribute: true,
119120
observer: '__editorPositionChanged',
121+
sync: true,
120122
},
121123

122124
/**
@@ -128,6 +130,7 @@ export const CrudMixin = (superClass) =>
128130
editOnClick: {
129131
type: Boolean,
130132
value: false,
133+
sync: true,
131134
},
132135

133136
/**
@@ -194,6 +197,7 @@ export const CrudMixin = (superClass) =>
194197
reflectToAttribute: true,
195198
notify: true,
196199
observer: '__editorOpenedChanged',
200+
sync: true,
197201
},
198202

199203
/**
@@ -218,6 +222,7 @@ export const CrudMixin = (superClass) =>
218222
type: Boolean,
219223
value: false,
220224
reflectToAttribute: true,
225+
sync: true,
221226
},
222227

223228
/**
@@ -261,6 +266,7 @@ export const CrudMixin = (superClass) =>
261266
*/
262267
i18n: {
263268
type: Object,
269+
sync: true,
264270
value() {
265271
return {
266272
newItem: 'New item',
@@ -295,7 +301,10 @@ export const CrudMixin = (superClass) =>
295301
__dialogAriaLabel: String,
296302

297303
/** @private */
298-
__isDirty: Boolean,
304+
__isDirty: {
305+
type: Boolean,
306+
sync: true,
307+
},
299308

300309
/** @private */
301310
__isNew: Boolean,
@@ -307,6 +316,7 @@ export const CrudMixin = (superClass) =>
307316
_fullscreen: {
308317
type: Boolean,
309318
observer: '__fullscreenChanged',
319+
sync: true,
310320
},
311321

312322
/**
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @license
3+
* Copyright (c) 2000 - 2024 Vaadin Ltd.
4+
*
5+
* This program is available under Vaadin Commercial License and Service Terms.
6+
*
7+
*
8+
* See https://vaadin.com/commercial-license-and-service-terms for the full
9+
* license.
10+
*/
11+
export * from './vaadin-crud-dialog.js';
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/**
2+
* @license
3+
* Copyright (c) 2000 - 2024 Vaadin Ltd.
4+
*
5+
* This program is available under Vaadin Commercial License and Service Terms.
6+
*
7+
*
8+
* See https://vaadin.com/commercial-license-and-service-terms for the full
9+
* license.
10+
*/
11+
import { css, html, LitElement } from 'lit';
12+
import { ifDefined } from 'lit/directives/if-defined.js';
13+
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
14+
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
15+
import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
16+
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
17+
import { DialogBaseMixin } from '@vaadin/dialog/src/vaadin-dialog-base-mixin.js';
18+
import { dialogOverlay, resizableOverlay } from '@vaadin/dialog/src/vaadin-dialog-styles.js';
19+
import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
20+
import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
21+
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
22+
import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
23+
import { crudDialogOverlayStyles } from './vaadin-crud-styles.js';
24+
25+
/**
26+
* An element used internally by `<vaadin-crud>`. Not intended to be used separately.
27+
*
28+
* @extends HTMLElement
29+
* @mixes DirMixin
30+
* @mixes OverlayMixin
31+
* @mixes ThemableMixin
32+
* @private
33+
*/
34+
class CrudDialogOverlay extends OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LitElement)))) {
35+
static get is() {
36+
return 'vaadin-crud-dialog-overlay';
37+
}
38+
39+
static get styles() {
40+
return [overlayStyles, dialogOverlay, resizableOverlay, crudDialogOverlayStyles];
41+
}
42+
43+
/** @protected */
44+
render() {
45+
return html`
46+
<div part="backdrop" id="backdrop" ?hidden="${!this.withBackdrop}"></div>
47+
<div part="overlay" id="overlay" tabindex="0">
48+
<section id="resizerContainer" class="resizer-container">
49+
<header part="header"><slot name="header"></slot></header>
50+
<div part="content" id="content">
51+
<slot name="form"></slot>
52+
</div>
53+
<footer part="footer" role="toolbar">
54+
<slot name="save-button"></slot>
55+
<slot name="cancel-button"></slot>
56+
<slot name="delete-button"></slot>
57+
</footer>
58+
</section>
59+
</div>
60+
`;
61+
}
62+
63+
/**
64+
* @protected
65+
* @override
66+
*/
67+
ready() {
68+
super.ready();
69+
70+
// CRUD has header and footer but does not use renderers
71+
this.setAttribute('has-header', '');
72+
this.setAttribute('has-footer', '');
73+
}
74+
}
75+
76+
defineCustomElement(CrudDialogOverlay);
77+
78+
/**
79+
* An element used internally by `<vaadin-crud>`. Not intended to be used separately.
80+
* @private
81+
*/
82+
class CrudDialog extends DialogBaseMixin(OverlayClassMixin(ThemePropertyMixin(PolylitMixin(LitElement)))) {
83+
static get is() {
84+
return 'vaadin-crud-dialog';
85+
}
86+
87+
static get styles() {
88+
return css`
89+
:host {
90+
display: none;
91+
}
92+
`;
93+
}
94+
95+
static get properties() {
96+
return {
97+
ariaLabel: {
98+
type: String,
99+
},
100+
101+
fullscreen: {
102+
type: Boolean,
103+
},
104+
};
105+
}
106+
107+
/** @protected */
108+
render() {
109+
return html`
110+
<vaadin-crud-dialog-overlay
111+
id="overlay"
112+
.opened="${this.opened}"
113+
aria-label="${ifDefined(this.ariaLabel)}"
114+
@opened-changed="${this._onOverlayOpened}"
115+
@mousedown="${this._bringOverlayToFront}"
116+
@touchstart="${this._bringOverlayToFront}"
117+
theme="${ifDefined(this._theme)}"
118+
.modeless="${this.modeless}"
119+
.withBackdrop="${!this.modeless}"
120+
?fullscreen="${this.fullscreen}"
121+
role="dialog"
122+
focus-trap
123+
></vaadin-crud-dialog-overlay>
124+
`;
125+
}
126+
}
127+
128+
defineCustomElement(CrudDialog);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @license
3+
* Copyright (c) 2000 - 2024 Vaadin Ltd.
4+
*
5+
* This program is available under Vaadin Commercial License and Service Terms.
6+
*
7+
*
8+
* See https://vaadin.com/commercial-license-and-service-terms for the full
9+
* license.
10+
*/
11+
export * from './vaadin-crud-edit-column.js';

0 commit comments

Comments
 (0)