move into web components

This commit is contained in:
Niels Lyngsø
2024-01-12 13:27:13 +01:00
parent cef01f54a3
commit 5d682929d7
4 changed files with 175 additions and 96 deletions

View File

@@ -1,87 +1,13 @@
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, customElement, LitElement, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
import { UmbSorterConfig, UmbSorterController } from '@umbraco-cms/backoffice/sorter';
type ModelEntryType = {
name: string;
};
const SORTER_CONFIG: UmbSorterConfig<ModelEntryType> = {
compareElementToModel: (element: HTMLElement, model: ModelEntryType) => {
return element.getAttribute('data-name') === model.name;
},
querySelectModelToElement: (container: HTMLElement, modelEntry: ModelEntryType) => {
return container.querySelector('data-name[' + modelEntry.name + ']');
},
identifier: 'string-that-identifies-all-example-sorters',
itemSelector: '.sorter-item',
containerSelector: '.sorter-container',
placeholderClass: 'sorter-placeholder',
};
import './sorter-group.js';
@customElement('example-sorter-dashboard')
export class ExampleSorterDashboard extends UmbElementMixin(LitElement) {
@state()
_items: ModelEntryType[] = [
{
name: 'Apple',
},
{
name: 'Banana',
},
{
name: 'Pear',
},
{
name: 'Pineapple',
},
{
name: 'Lemon',
},
];
#sorter = new UmbSorterController(this, {
...SORTER_CONFIG,
performItemInsert: ({ item, newIndex }) => {
this._items.splice(newIndex, 0, item);
console.log('inserted', item.name, 'at', newIndex, ' ', this._items.map((x) => x.name).join(', '));
this.requestUpdate('_items');
return true;
},
performItemRemove: ({ item }) => {
const indexToMove = this._items.findIndex((x) => x.name === item.name);
this._items.splice(indexToMove, 1);
console.log('removed', item.name, 'at', indexToMove, ' ', this._items.map((x) => x.name).join(', '));
this.requestUpdate('_items');
return true;
},
});
constructor() {
super();
this.#sorter.setModel(this._items);
}
removeItem = (item: ModelEntryType) => {
this._items = this._items.filter((r) => r.name !== item.name);
this.#sorter.setModel(this._items);
};
render() {
return html`
<uui-box class="uui-text">
<div class="sorter-container">
${repeat(
this._items,
(item) => item.name,
(item) =>
html`<div class="sorter-item" data-name=${item.name}>
${item.name} <button @click=${() => this.removeItem(item)}>Delete</button>
<!-- make something that visually takes some time to display, like a large image.-->
</div>`,
)}
</div>
<uui-box class="uui-text outer-wrapper">
<example-sorter-group></example-sorter-group>
</uui-box>
`;
}
@@ -94,17 +20,9 @@ export class ExampleSorterDashboard extends UmbElementMixin(LitElement) {
padding: var(--uui-size-layout-1);
}
.sorter-item {
.outer-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--uui-size-layout-1);
border: 1px solid var(--uui-color-border);
border-radius: var(--uui-border-radius);
margin-bottom: 3px;
}
.sorter-placeholder {
opacity: 0.2;
flex-direction: row;
}
`,
];

View File

@@ -0,0 +1,107 @@
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, customElement, LitElement, state, repeat } from '@umbraco-cms/backoffice/external/lit';
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
import { UmbSorterConfig, UmbSorterController } from '@umbraco-cms/backoffice/sorter';
import './sorter-item.js';
type ModelEntryType = {
name: string;
};
const SORTER_CONFIG: UmbSorterConfig<ModelEntryType> = {
compareElementToModel: (element: HTMLElement, model: ModelEntryType) => {
return element.getAttribute('name') === model.name;
},
querySelectModelToElement: (container: HTMLElement, modelEntry: ModelEntryType) => {
return container.querySelector('name[' + modelEntry.name + ']');
},
identifier: 'string-that-identifies-all-example-sorters',
itemSelector: 'example-sorter-item',
containerSelector: '.sorter-container',
};
@customElement('example-sorter-group')
export class ExampleSorterGroup extends UmbElementMixin(LitElement) {
@state()
_items: ModelEntryType[] = [
{
name: 'Apple',
},
{
name: 'Banana',
},
{
name: 'Pear',
},
{
name: 'Pineapple',
},
{
name: 'Lemon',
},
];
#sorter = new UmbSorterController(this, {
...SORTER_CONFIG,
performItemInsert: ({ item, newIndex }) => {
this._items.splice(newIndex, 0, item);
console.log('inserted', item.name, 'at', newIndex, ' ', this._items.map((x) => x.name).join(', '));
this.requestUpdate('_items');
return true;
},
performItemRemove: ({ item }) => {
const indexToMove = this._items.findIndex((x) => x.name === item.name);
this._items.splice(indexToMove, 1);
console.log('removed', item.name, 'at', indexToMove, ' ', this._items.map((x) => x.name).join(', '));
this.requestUpdate('_items');
return true;
},
});
constructor() {
super();
this.#sorter.setModel(this._items);
}
removeItem = (item: ModelEntryType) => {
this._items = this._items.filter((r) => r.name !== item.name);
this.#sorter.setModel(this._items);
};
render() {
return html`
<div class="sorter-container">
${repeat(
this._items,
(item) => item.name,
(item) =>
html`<example-sorter-item name=${item.name}>
<button @click=${() => this.removeItem(item)}>Delete</button>
</example-sorter-item>`,
)}
</div>
`;
}
static styles = [
UmbTextStyles,
css`
:host {
display: block;
}
.sorter-placeholder {
opacity: 0.2;
}
`,
];
}
export default ExampleSorterGroup;
declare global {
interface HTMLElementTagNameMap {
'example-sorter-group': ExampleSorterGroup;
}
}

View File

@@ -0,0 +1,46 @@
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { css, html, customElement, LitElement, state, repeat, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
import { UmbSorterConfig, UmbSorterController } from '@umbraco-cms/backoffice/sorter';
@customElement('example-sorter-item')
export class ExampleSorterItem extends UmbElementMixin(LitElement) {
@property({ type: String, reflect: true })
name: string = '';
@property({ type: Boolean, reflect: true, attribute: 'drag-placeholder' })
umbDragPlaceholder = false;
render() {
return html`
${this.name}
<slot></slot>
`;
}
static styles = [
UmbTextStyles,
css`
:host {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--uui-size-layout-1);
border: 1px solid var(--uui-color-border);
border-radius: var(--uui-border-radius);
margin-bottom: 3px;
}
:host[drag-placeholder] {
opacity: 0.2;
}
`,
];
}
export default ExampleSorterItem;
declare global {
interface HTMLElementTagNameMap {
'example-sorter-item': ExampleSorterItem;
}
}