Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

experiment: add LitElement based version of vaadin-crud #8346

Merged
merged 8 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 3 additions & 15 deletions packages/crud/src/vaadin-crud-edit-column.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import './vaadin-crud-edit.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { GridColumn } from '@vaadin/grid/src/vaadin-grid-column.js';
import { editColumnDefaultRenderer } from './vaadin-crud-helpers.js';

/**
* `<vaadin-crud-edit-column>` is a helper element for the `<vaadin-grid>`
Expand Down Expand Up @@ -69,21 +70,8 @@ class CrudEditColumn extends GridColumn {
*
* @override
*/
_defaultRenderer(root, _column) {
let edit = root.firstElementChild;
if (!edit) {
edit = document.createElement('vaadin-crud-edit');
if (this.hasAttribute('theme')) {
edit.setAttribute('theme', this.getAttribute('theme'));
}
root.appendChild(edit);
}

if (this.ariaLabel) {
edit.setAttribute('aria-label', this.ariaLabel);
} else {
edit.removeAttribute('aria-label');
}
_defaultRenderer(root, column) {
editColumnDefaultRenderer(root, column);
}
}

Expand Down
25 changes: 3 additions & 22 deletions packages/crud/src/vaadin-crud-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import '@vaadin/text-field/src/vaadin-text-field.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { FormLayout } from '@vaadin/form-layout/src/vaadin-form-layout.js';
import { capitalize } from './vaadin-crud-helpers.js';
import { createField, createFields } from './vaadin-crud-helpers.js';
import { IncludedMixin } from './vaadin-crud-include-mixin.js';

/**
Expand Down Expand Up @@ -64,31 +64,12 @@ class CrudForm extends IncludedMixin(FormLayout) {

/** @private */
__createField(parent, path) {
const field = document.createElement('vaadin-text-field');
field.label = capitalize(path);
field.path = path;
field.required = true;
parent.appendChild(field);
this._fields.push(field);
return field;
return createField(this, parent, path);
}

/** @private */
__createFields(parent, object, path) {
Object.keys(object).forEach((prop) => {
if (!this.include && this.exclude && this.exclude.test(prop)) {
return;
}
const newPath = (path ? `${path}.` : '') + prop;
if (object[prop] && typeof object[prop] === 'object') {
this.__createFields(parent, object[prop], newPath);
} else {
this.__createField(parent, newPath);
}
});
if (!this._fields.length) {
this._fields = undefined;
}
return createFields(this, parent, object, path);
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/crud/src/vaadin-crud-grid-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const CrudGridMixin = (superClass) =>
*/
hideEditColumn: {
type: Boolean,
sync: true,
},
};
}
Expand Down
44 changes: 44 additions & 0 deletions packages/crud/src/vaadin-crud-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,47 @@ export function setProperty(path, value, obj) {
export function isValidEditorPosition(editorPosition) {
return ['bottom', 'aside'].includes(editorPosition);
}

export function editColumnDefaultRenderer(root, column) {
let edit = root.firstElementChild;
if (!edit) {
edit = document.createElement('vaadin-crud-edit');
if (column.hasAttribute('theme')) {
edit.setAttribute('theme', column.getAttribute('theme'));
}
root.appendChild(edit);
}

if (column.ariaLabel) {
edit.setAttribute('aria-label', column.ariaLabel);
} else {
edit.removeAttribute('aria-label');
}
}

export function createField(crudForm, parent, path) {
const field = document.createElement('vaadin-text-field');
field.label = capitalize(path);
field.path = path;
field.required = true;
parent.appendChild(field);
crudForm._fields.push(field);
return field;
}

export function createFields(crudForm, parent, object, path) {
Object.keys(object).forEach((prop) => {
if (!crudForm.include && crudForm.exclude && crudForm.exclude.test(prop)) {
return;
}
const newPath = (path ? `${path}.` : '') + prop;
if (object[prop] && typeof object[prop] === 'object') {
createFields(crudForm, parent, object[prop], newPath);
} else {
createField(crudForm, parent, newPath);
}
});
if (!crudForm._fields.length) {
crudForm._fields = undefined;
}
}
2 changes: 2 additions & 0 deletions packages/crud/src/vaadin-crud-include-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const IncludedMixin = (superClass) =>
exclude: {
value: '^_',
observer: '__onExcludeChange',
sync: true,
},

/**
Expand All @@ -40,6 +41,7 @@ export const IncludedMixin = (superClass) =>
*/
include: {
observer: '__onIncludeChange',
sync: true,
},
};
}
Expand Down
12 changes: 11 additions & 1 deletion packages/crud/src/vaadin-crud-mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export const CrudMixin = (superClass) =>
type: Object,
observer: '__editedItemChanged',
notify: true,
sync: true,
},

/**
Expand All @@ -117,6 +118,7 @@ export const CrudMixin = (superClass) =>
value: '',
reflectToAttribute: true,
observer: '__editorPositionChanged',
sync: true,
},

/**
Expand All @@ -128,6 +130,7 @@ export const CrudMixin = (superClass) =>
editOnClick: {
type: Boolean,
value: false,
sync: true,
},

/**
Expand Down Expand Up @@ -194,6 +197,7 @@ export const CrudMixin = (superClass) =>
reflectToAttribute: true,
notify: true,
observer: '__editorOpenedChanged',
sync: true,
},

/**
Expand All @@ -218,6 +222,7 @@ export const CrudMixin = (superClass) =>
type: Boolean,
value: false,
reflectToAttribute: true,
sync: true,
},

/**
Expand Down Expand Up @@ -261,6 +266,7 @@ export const CrudMixin = (superClass) =>
*/
i18n: {
type: Object,
sync: true,
value() {
return {
newItem: 'New item',
Expand Down Expand Up @@ -295,7 +301,10 @@ export const CrudMixin = (superClass) =>
__dialogAriaLabel: String,

/** @private */
__isDirty: Boolean,
__isDirty: {
type: Boolean,
sync: true,
},

/** @private */
__isNew: Boolean,
Expand All @@ -307,6 +316,7 @@ export const CrudMixin = (superClass) =>
_fullscreen: {
type: Boolean,
observer: '__fullscreenChanged',
sync: true,
},

/**
Expand Down
11 changes: 11 additions & 0 deletions packages/crud/src/vaadin-lit-crud-dialog.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @license
* Copyright (c) 2000 - 2024 Vaadin Ltd.
*
* This program is available under Vaadin Commercial License and Service Terms.
*
*
* See https://vaadin.com/commercial-license-and-service-terms for the full
* license.
*/
export * from './vaadin-crud-dialog.js';
128 changes: 128 additions & 0 deletions packages/crud/src/vaadin-lit-crud-dialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* @license
* Copyright (c) 2000 - 2024 Vaadin Ltd.
*
* This program is available under Vaadin Commercial License and Service Terms.
*
*
* See https://vaadin.com/commercial-license-and-service-terms for the full
* license.
*/
import { css, html, LitElement } from 'lit';
import { ifDefined } from 'lit/directives/if-defined.js';
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
import { OverlayClassMixin } from '@vaadin/component-base/src/overlay-class-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { DialogBaseMixin } from '@vaadin/dialog/src/vaadin-dialog-base-mixin.js';
import { dialogOverlay, resizableOverlay } from '@vaadin/dialog/src/vaadin-dialog-styles.js';
import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
import { overlayStyles } from '@vaadin/overlay/src/vaadin-overlay-styles.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
import { crudDialogOverlayStyles } from './vaadin-crud-styles.js';
web-padawan marked this conversation as resolved.
Show resolved Hide resolved

/**
* An element used internally by `<vaadin-crud>`. Not intended to be used separately.
*
* @extends HTMLElement
* @mixes DirMixin
* @mixes OverlayMixin
* @mixes ThemableMixin
* @private
*/
class CrudDialogOverlay extends OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LitElement)))) {
static get is() {
return 'vaadin-crud-dialog-overlay';
}

static get styles() {
return [overlayStyles, dialogOverlay, resizableOverlay, crudDialogOverlayStyles];
}

/** @protected */
render() {
web-padawan marked this conversation as resolved.
Show resolved Hide resolved
return html`
<div part="backdrop" id="backdrop" ?hidden="${!this.withBackdrop}"></div>
<div part="overlay" id="overlay" tabindex="0">
<section id="resizerContainer" class="resizer-container">
<header part="header"><slot name="header"></slot></header>
<div part="content" id="content">
<slot name="form"></slot>
</div>
<footer part="footer" role="toolbar">
<slot name="save-button"></slot>
<slot name="cancel-button"></slot>
<slot name="delete-button"></slot>
</footer>
</section>
</div>
`;
}

/**
* @protected
* @override
*/
ready() {
super.ready();

// CRUD has header and footer but does not use renderers
this.setAttribute('has-header', '');
this.setAttribute('has-footer', '');
}
}

defineCustomElement(CrudDialogOverlay);

/**
* An element used internally by `<vaadin-crud>`. Not intended to be used separately.
* @private
*/
class CrudDialog extends DialogBaseMixin(OverlayClassMixin(ThemePropertyMixin(PolylitMixin(LitElement)))) {
static get is() {
return 'vaadin-crud-dialog';
}

static get styles() {
return css`
:host {
display: none;
}
`;
}

static get properties() {
return {
ariaLabel: {
type: String,
},

fullscreen: {
type: Boolean,
},
};
}

/** @protected */
render() {
web-padawan marked this conversation as resolved.
Show resolved Hide resolved
return html`
<vaadin-crud-dialog-overlay
id="overlay"
.opened="${this.opened}"
aria-label="${ifDefined(this.ariaLabel)}"
@opened-changed="${this._onOverlayOpened}"
@mousedown="${this._bringOverlayToFront}"
@touchstart="${this._bringOverlayToFront}"
theme="${ifDefined(this._theme)}"
.modeless="${this.modeless}"
.withBackdrop="${!this.modeless}"
?fullscreen="${this.fullscreen}"
role="dialog"
focus-trap
></vaadin-crud-dialog-overlay>
`;
}
}

defineCustomElement(CrudDialog);
11 changes: 11 additions & 0 deletions packages/crud/src/vaadin-lit-crud-edit-column.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* @license
* Copyright (c) 2000 - 2024 Vaadin Ltd.
*
* This program is available under Vaadin Commercial License and Service Terms.
*
*
* See https://vaadin.com/commercial-license-and-service-terms for the full
* license.
*/
export * from './vaadin-crud-edit-column.js';
Loading
Loading