Merge remote-tracking branch 'origin/main' into feature/property-editor-multi-url-picker
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
import { UUIBooleanInputEvent } from '@umbraco-ui/uui';
|
||||
@@ -21,21 +21,21 @@ export class UmbInputCheckboxListElement extends FormControlMixin(UmbLitElement)
|
||||
* List of items.
|
||||
*/
|
||||
@property()
|
||||
list?: [];
|
||||
public list: Array<{ key: string; checked: boolean; value: string }> = [];
|
||||
|
||||
private _selectedKeys: Array<string> = [];
|
||||
public get selectedKeys(): Array<string> {
|
||||
return this._selectedKeys;
|
||||
#selected: Array<string> = [];
|
||||
public get selected(): Array<string> {
|
||||
return this.#selected;
|
||||
}
|
||||
public set selectedKeys(keys: Array<string>) {
|
||||
this._selectedKeys = keys;
|
||||
public set selected(keys: Array<string>) {
|
||||
this.#selected = keys;
|
||||
super.value = keys.join(',');
|
||||
}
|
||||
|
||||
@property()
|
||||
public set value(keysString: string) {
|
||||
if (keysString !== this._value) {
|
||||
this.selectedKeys = keysString.split(/[ ,]+/);
|
||||
this.selected = keysString.split(/[ ,]+/);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,32 +43,32 @@ export class UmbInputCheckboxListElement extends FormControlMixin(UmbLitElement)
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _setSelection(e: UUIBooleanInputEvent) {
|
||||
#setSelection(e: UUIBooleanInputEvent) {
|
||||
e.stopPropagation();
|
||||
if (e.target.checked) this.selectedKeys = [...this.selectedKeys, e.target.value];
|
||||
else this._removeFromSelection(this.selectedKeys.findIndex((key) => e.target.value === key));
|
||||
if (e.target.checked) this.selected = [...this.selected, e.target.value];
|
||||
else this.#removeFromSelection(this.selected.findIndex((key) => e.target.value === key));
|
||||
|
||||
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
||||
}
|
||||
|
||||
private _removeFromSelection(index: number) {
|
||||
#removeFromSelection(index: number) {
|
||||
if (index == -1) return;
|
||||
const keys = [...this.selectedKeys];
|
||||
const keys = [...this.selected];
|
||||
keys.splice(index, 1);
|
||||
this.selectedKeys = keys;
|
||||
this.selected = keys;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.list) return nothing;
|
||||
return html`<form>
|
||||
<uui-form @change="${this._setSelection}">
|
||||
<uui-form @change="${this.#setSelection}">
|
||||
${repeat(this.list, (item) => item.key, this.renderCheckbox)}
|
||||
</uui-form>
|
||||
</form>`;
|
||||
}
|
||||
|
||||
renderCheckbox(item: any) {
|
||||
return html`<uui-checkbox value="${item.key}" label="${item.label}"></uui-checkbox>`;
|
||||
renderCheckbox(item: { key: string; checked: boolean; value: string }) {
|
||||
return html`<uui-checkbox value="${item.value}" label="${item.value}" ?checked="${item.checked}"></uui-checkbox>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
import { UUIBooleanInputEvent } from '@umbraco-ui/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
|
||||
@customElement('umb-input-radio-button-list')
|
||||
export class UmbInputRadioButtonListElement extends FormControlMixin(UmbLitElement) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
/**
|
||||
* List of items.
|
||||
*/
|
||||
@property()
|
||||
public list: Array<{ key: string; sortOrder: number; value: string }> = [];
|
||||
|
||||
#selected = '';
|
||||
public get selected(): string {
|
||||
return this.#selected;
|
||||
}
|
||||
public set selected(key: string) {
|
||||
this.#selected = key;
|
||||
super.value = key;
|
||||
}
|
||||
|
||||
@property()
|
||||
public set value(key: string) {
|
||||
if (key !== this._value) {
|
||||
this.selected = key;
|
||||
}
|
||||
}
|
||||
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
#setSelection(e: UUIBooleanInputEvent) {
|
||||
e.stopPropagation();
|
||||
if (e.target.value) this.selected = e.target.value;
|
||||
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.list) return nothing;
|
||||
|
||||
return html`<uui-radio-group .value=${this.value} @change=${this.#setSelection}>
|
||||
${repeat(this.list, (item) => item, this.renderRadioButton)}
|
||||
</uui-radio-group>`;
|
||||
}
|
||||
|
||||
renderRadioButton(item: { key: string; sortOrder: number; value: string }) {
|
||||
return html`<uui-radio value="${item.value}" label="${item.value}"></uui-radio>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbInputRadioButtonListElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-input-radio-button-list': UmbInputRadioButtonListElement;
|
||||
}
|
||||
}
|
||||
@@ -12,35 +12,48 @@ import type { DataTypePropertyModel } from '@umbraco-cms/backend-api';
|
||||
export class UmbPropertyEditorUICheckboxListElement extends UmbLitElement {
|
||||
static styles = [UUITextStyles];
|
||||
|
||||
private _value: Array<string> = [];
|
||||
#value: Array<string> = [];
|
||||
@property({ type: Array })
|
||||
public get value(): Array<string> {
|
||||
return this._value;
|
||||
return this.#value;
|
||||
}
|
||||
public set value(value: Array<string>) {
|
||||
this._value = value || [];
|
||||
this.#value = value || [];
|
||||
}
|
||||
|
||||
@property({ type: Array, attribute: false })
|
||||
public set config(config: Array<DataTypePropertyModel>) {
|
||||
const listData = config.find((x) => x.alias === 'itemList');
|
||||
const listData = config.find((x) => x.alias === 'items');
|
||||
|
||||
if (!listData) return;
|
||||
this._list = listData.value;
|
||||
|
||||
// formatting the items in the dictionary into an array
|
||||
const sortedItems = [];
|
||||
const values = Object.values<{ value: string; sortOrder: number }>(listData.value);
|
||||
const keys = Object.keys(listData.value);
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
sortedItems.push({ key: keys[i], sortOrder: values[i].sortOrder, value: values[i].value });
|
||||
}
|
||||
// ensure the items are sorted by the provided sort order
|
||||
sortedItems.sort((a, b) => {
|
||||
return a.sortOrder > b.sortOrder ? 1 : b.sortOrder > a.sortOrder ? -1 : 0;
|
||||
});
|
||||
|
||||
this._list = sortedItems.map((x) => ({ key: x.key, checked: this.#value.includes(x.value), value: x.value }));
|
||||
}
|
||||
|
||||
@state()
|
||||
private _list: [] = [];
|
||||
private _list: Array<{ key: string; checked: boolean; value: string }> = [];
|
||||
|
||||
private _onChange(event: CustomEvent) {
|
||||
this.value = (event.target as UmbInputCheckboxListElement).selectedKeys;
|
||||
#onChange(event: CustomEvent) {
|
||||
this.value = (event.target as UmbInputCheckboxListElement).selected;
|
||||
this.dispatchEvent(new CustomEvent('property-value-change'));
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<umb-input-checkbox-list
|
||||
@change="${this._onChange}"
|
||||
.selectedKeys="${this._value}"
|
||||
@change="${this.#onChange}"
|
||||
.selectedKeys="${this.#value}"
|
||||
.list="${this._list}"></umb-input-checkbox-list>`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { html } from 'lit';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import '../../../components/input-radio-button-list/input-radio-button-list.element';
|
||||
import type { UmbInputRadioButtonListElement } from '../../../components/input-radio-button-list/input-radio-button-list.element';
|
||||
import { UmbLitElement } from '@umbraco-cms/element';
|
||||
import type { DataTypePropertyModel } from '@umbraco-cms/backend-api';
|
||||
|
||||
/**
|
||||
* @element umb-property-editor-ui-radio-button-list
|
||||
@@ -10,14 +13,50 @@ import { UmbLitElement } from '@umbraco-cms/element';
|
||||
export class UmbPropertyEditorUIRadioButtonListElement extends UmbLitElement {
|
||||
static styles = [UUITextStyles];
|
||||
|
||||
@property()
|
||||
value = '';
|
||||
#value = '';
|
||||
@property({ type: String })
|
||||
public get value(): string {
|
||||
return this.#value;
|
||||
}
|
||||
public set value(value: string) {
|
||||
this.#value = value || '';
|
||||
}
|
||||
|
||||
@property({ type: Array, attribute: false })
|
||||
public config = [];
|
||||
public set config(config: Array<DataTypePropertyModel>) {
|
||||
const listData = config.find((x) => x.alias === 'items');
|
||||
|
||||
if (!listData) return;
|
||||
|
||||
// formatting the items in the dictionary into an array
|
||||
const sortedItems = [];
|
||||
const values = Object.values<{ value: string; sortOrder: number }>(listData.value);
|
||||
const keys = Object.keys(listData.value);
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
sortedItems.push({ key: keys[i], sortOrder: values[i].sortOrder, value: values[i].value });
|
||||
}
|
||||
|
||||
// ensure the items are sorted by the provided sort order
|
||||
sortedItems.sort((a, b) => {
|
||||
return a.sortOrder > b.sortOrder ? 1 : b.sortOrder > a.sortOrder ? -1 : 0;
|
||||
});
|
||||
|
||||
this._list = sortedItems;
|
||||
}
|
||||
|
||||
@state()
|
||||
private _list: Array<{ key: string; sortOrder: number; value: string }> = [];
|
||||
|
||||
#onChange(event: CustomEvent) {
|
||||
this.value = (event.target as UmbInputRadioButtonListElement).selected;
|
||||
this.dispatchEvent(new CustomEvent('property-value-change'));
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<div>umb-property-editor-ui-radio-button-list</div>`;
|
||||
return html`<umb-input-radio-button-list
|
||||
@change="${this.#onChange}"
|
||||
.selectedKey="${this.#value}"
|
||||
.list="${this._list}"></umb-input-radio-button-list>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -239,7 +239,16 @@ export const data: Array<DataTypeModel & { type: 'data-type' }> = [
|
||||
parentKey: null,
|
||||
propertyEditorAlias: 'Umbraco.RadioButtonList',
|
||||
propertyEditorUiAlias: 'Umb.PropertyEditorUI.RadioButtonList',
|
||||
data: [],
|
||||
data: [
|
||||
{
|
||||
alias: 'items',
|
||||
value: {
|
||||
0: { sortOrder: 1, value: 'First Option' },
|
||||
1: { sortOrder: 2, value: 'Second Option' },
|
||||
2: { sortOrder: 3, value: 'I Am the third Option' },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'data-type',
|
||||
@@ -250,11 +259,12 @@ export const data: Array<DataTypeModel & { type: 'data-type' }> = [
|
||||
propertyEditorUiAlias: 'Umb.PropertyEditorUI.CheckboxList',
|
||||
data: [
|
||||
{
|
||||
alias: 'itemList',
|
||||
value: [
|
||||
{ label: 'Label 1', key: '123' },
|
||||
{ label: 'Label 2', key: '456' },
|
||||
],
|
||||
alias: 'items',
|
||||
value: {
|
||||
0: { sortOrder: 1, value: 'First Option' },
|
||||
1: { sortOrder: 2, value: 'Second Option' },
|
||||
2: { sortOrder: 3, value: 'I Am the third Option' },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user